home *** CD-ROM | disk | FTP | other *** search
/ PC go! 2013 December / PCGO_13-12_CD.iso / nw.pak / Unnamed File 000655.unknown < prev    next >
Encoding:
Text File  |  2012-12-14  |  92.9 KB  |  3,182 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7. WebInspector.RequestView = function(request)
  8. {
  9. WebInspector.View.call(this);
  10. this.registerRequiredCSS("resourceView.css");
  11.  
  12. this.element.addStyleClass("resource-view");
  13. this.request = request;
  14. }
  15.  
  16. WebInspector.RequestView.prototype = {
  17. hasContent: function()
  18. {
  19. return false;
  20. },
  21.  
  22. __proto__: WebInspector.View.prototype
  23. }
  24.  
  25.  
  26. WebInspector.RequestView.hasTextContent = function(request)
  27. {
  28. if (request.type.isTextType())
  29. return true; 
  30. if (request.type === WebInspector.resourceTypes.Other || request.hasErrorStatusCode())
  31. return request.content && !request.contentEncoded;
  32. return false;
  33. }
  34.  
  35.  
  36. WebInspector.RequestView.nonSourceViewForRequest = function(request)
  37. {
  38. switch (request.type) {
  39. case WebInspector.resourceTypes.Image:
  40. return new WebInspector.ImageView(request);
  41. case WebInspector.resourceTypes.Font:
  42. return new WebInspector.FontView(request);
  43. default:
  44. return new WebInspector.RequestView(request);
  45. }
  46. }
  47. ;
  48.  
  49.  
  50.  
  51. WebInspector.NetworkItemView = function(request)
  52. {
  53. WebInspector.TabbedPane.call(this);
  54. this.element.addStyleClass("network-item-view");
  55.  
  56. var headersView = new WebInspector.RequestHeadersView(request);
  57. this.appendTab("headers", WebInspector.UIString("Headers"), headersView);
  58.  
  59. this.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
  60.  
  61. if (request.frames().length > 0) {
  62. var frameView = new WebInspector.ResourceWebSocketFrameView(request);
  63. this.appendTab("webSocketFrames", WebInspector.UIString("Frames"), frameView);
  64. return;
  65. }
  66.  
  67. var responseView = new WebInspector.RequestResponseView(request);
  68. var previewView = new WebInspector.RequestPreviewView(request, responseView);
  69. this.appendTab("preview", WebInspector.UIString("Preview"), previewView);
  70. this.appendTab("response", WebInspector.UIString("Response"), responseView);
  71.  
  72. if (request.requestCookies || request.responseCookies) {
  73. this._cookiesView = new WebInspector.RequestCookiesView(request);
  74. this.appendTab("cookies", WebInspector.UIString("Cookies"), this._cookiesView);
  75. }
  76.  
  77. if (request.timing) {
  78. var timingView = new WebInspector.RequestTimingView(request);
  79. this.appendTab("timing", WebInspector.UIString("Timing"), timingView);
  80. }
  81. this._request = request;
  82. }
  83.  
  84. WebInspector.NetworkItemView.prototype = {
  85. wasShown: function()
  86. {
  87. WebInspector.TabbedPane.prototype.wasShown.call(this);
  88. this._selectTab();
  89. },
  90.  
  91.  
  92. _selectTab: function(tabId)
  93. {
  94. if (!tabId)
  95. tabId = WebInspector.settings.resourceViewTab.get();
  96.  
  97. if (!this.selectTab(tabId)) {
  98. this._isInFallbackSelection = true;
  99. this.selectTab("headers");
  100. delete this._isInFallbackSelection;
  101. }
  102. },
  103.  
  104. _tabSelected: function(event)
  105. {
  106. if (event.data.isUserGesture)
  107. WebInspector.settings.resourceViewTab.set(event.data.tabId);
  108. },
  109.  
  110.  
  111. request: function()
  112. {
  113. return this._request;
  114. },
  115.  
  116. __proto__: WebInspector.TabbedPane.prototype
  117. }
  118.  
  119.  
  120. WebInspector.RequestContentView = function(request)
  121. {
  122. WebInspector.RequestView.call(this, request);
  123. }
  124.  
  125. WebInspector.RequestContentView.prototype = {
  126. hasContent: function()
  127. {
  128. return true;
  129. },
  130.  
  131. get innerView()
  132. {
  133. return this._innerView;
  134. },
  135.  
  136. set innerView(innerView)
  137. {
  138. this._innerView = innerView;
  139. },
  140.  
  141. wasShown: function()
  142. {
  143. this._ensureInnerViewShown();
  144. },
  145.  
  146. _ensureInnerViewShown: function()
  147. {
  148. if (this._innerViewShowRequested)
  149. return;
  150. this._innerViewShowRequested = true;
  151.  
  152.  
  153. function callback(content, contentEncoded, mimeType)
  154. {
  155. this._innerViewShowRequested = false;
  156. this.contentLoaded();
  157. }
  158.  
  159. this.request.requestContent(callback.bind(this));
  160. },
  161.  
  162. contentLoaded: function()
  163. {
  164.  
  165. },
  166.  
  167. canHighlightLine: function()
  168. {
  169. return this._innerView && this._innerView.canHighlightLine();
  170. },
  171.  
  172. highlightLine: function(line)
  173. {
  174. if (this.canHighlightLine())
  175. this._innerView.highlightLine(line);
  176. },
  177.  
  178. __proto__: WebInspector.RequestView.prototype
  179. }
  180. ;
  181.  
  182.  
  183.  
  184. WebInspector.RequestCookiesView = function(request)
  185. {
  186. WebInspector.View.call(this);
  187. this.element.addStyleClass("resource-cookies-view");
  188.  
  189. this._request = request;
  190.  
  191. request.addEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged, this._refreshCookies, this);
  192. request.addEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged, this._refreshCookies, this);
  193. }
  194.  
  195. WebInspector.RequestCookiesView.prototype = {
  196. wasShown: function()
  197. {
  198. if (!this._gotCookies) {
  199. if (!this._emptyView) {
  200. this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("This request has no cookies."));
  201. this._emptyView.show(this.element);
  202. }
  203. return;
  204. }
  205.  
  206. if (!this._cookiesTable)
  207. this._buildCookiesTable();
  208. },
  209.  
  210. get _gotCookies()
  211. {
  212. return (this._request.requestCookies && this._request.requestCookies.length) || (this._request.responseCookies && this._request.responseCookies.length);
  213. },
  214.  
  215. _buildCookiesTable: function()
  216. {
  217. this.detachChildViews();
  218.  
  219. this._cookiesTable = new WebInspector.CookiesTable(null, true);
  220. this._cookiesTable.addCookiesFolder(WebInspector.UIString("Request Cookies"), this._request.requestCookies);
  221. this._cookiesTable.addCookiesFolder(WebInspector.UIString("Response Cookies"), this._request.responseCookies);
  222. this._cookiesTable.show(this.element);
  223. },
  224.  
  225. _refreshCookies: function()
  226. {
  227. delete this._cookiesTable;
  228. if (!this._gotCookies || !this.isShowing())
  229. return;
  230. this._buildCookiesTable();
  231. this._cookiesTable.updateWidths();
  232. },
  233.  
  234. __proto__: WebInspector.View.prototype
  235. }
  236. ;
  237.  
  238.  
  239.  
  240. WebInspector.RequestHeadersView = function(request)
  241. {
  242. WebInspector.View.call(this);
  243. this.registerRequiredCSS("resourceView.css");
  244. this.element.addStyleClass("resource-headers-view");
  245.  
  246. this._request = request;
  247.  
  248. this._headersListElement = document.createElement("ol");
  249. this._headersListElement.className = "outline-disclosure";
  250. this.element.appendChild(this._headersListElement);
  251.  
  252. this._headersTreeOutline = new TreeOutline(this._headersListElement);
  253. this._headersTreeOutline.expandTreeElementsWhenArrowing = true;
  254.  
  255. this._urlTreeElement = new TreeElement("", null, false);
  256. this._urlTreeElement.selectable = false;
  257. this._headersTreeOutline.appendChild(this._urlTreeElement);
  258.  
  259. this._requestMethodTreeElement = new TreeElement("", null, false);
  260. this._requestMethodTreeElement.selectable = false;
  261. this._headersTreeOutline.appendChild(this._requestMethodTreeElement);
  262.  
  263. this._statusCodeTreeElement = new TreeElement("", null, false);
  264. this._statusCodeTreeElement.selectable = false;
  265. this._headersTreeOutline.appendChild(this._statusCodeTreeElement);
  266.  
  267. this._requestHeadersTreeElement = new TreeElement("", null, true);
  268. this._requestHeadersTreeElement.expanded = true;
  269. this._requestHeadersTreeElement.selectable = false;
  270. this._headersTreeOutline.appendChild(this._requestHeadersTreeElement);
  271.  
  272. this._decodeRequestParameters = true;
  273.  
  274. this._showRequestHeadersText = false;
  275. this._showResponseHeadersText = false;
  276.  
  277. this._queryStringTreeElement = new TreeElement("", null, true);
  278. this._queryStringTreeElement.expanded = true;
  279. this._queryStringTreeElement.selectable = false;
  280. this._queryStringTreeElement.hidden = true;
  281. this._headersTreeOutline.appendChild(this._queryStringTreeElement);
  282.  
  283. this._urlFragmentTreeElement = new TreeElement("", null, true);
  284. this._urlFragmentTreeElement.expanded = true;
  285. this._urlFragmentTreeElement.selectable = false;
  286. this._urlFragmentTreeElement.hidden = true;
  287. this._headersTreeOutline.appendChild(this._urlFragmentTreeElement);
  288.  
  289. this._formDataTreeElement = new TreeElement("", null, true);
  290. this._formDataTreeElement.expanded = true;
  291. this._formDataTreeElement.selectable = false;
  292. this._formDataTreeElement.hidden = true;
  293. this._headersTreeOutline.appendChild(this._formDataTreeElement);
  294.  
  295. this._requestPayloadTreeElement = new TreeElement(WebInspector.UIString("Request Payload"), null, true);
  296. this._requestPayloadTreeElement.expanded = true;
  297. this._requestPayloadTreeElement.selectable = false;
  298. this._requestPayloadTreeElement.hidden = true;
  299. this._headersTreeOutline.appendChild(this._requestPayloadTreeElement);
  300.  
  301. this._responseHeadersTreeElement = new TreeElement("", null, true);
  302. this._responseHeadersTreeElement.expanded = true;
  303. this._responseHeadersTreeElement.selectable = false;
  304. this._headersTreeOutline.appendChild(this._responseHeadersTreeElement);
  305.  
  306. request.addEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
  307. request.addEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
  308. request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
  309.  
  310. this._refreshURL();
  311. this._refreshQueryString();
  312. this._refreshUrlFragment();
  313. this._refreshRequestHeaders();
  314. this._refreshResponseHeaders();
  315. this._refreshHTTPInformation();
  316. }
  317.  
  318. WebInspector.RequestHeadersView.prototype = {
  319.  
  320. _formatHeader: function(name, value)
  321. {
  322. var fragment = document.createDocumentFragment();
  323. fragment.createChild("div", "header-name").textContent = name + ":";
  324. fragment.createChild("div", "header-value source-code").textContent = value;
  325.  
  326. return fragment;
  327. },
  328.  
  329.  
  330. _formatParameter: function(value, className, decodeParameters)
  331. {
  332. var errorDecoding = false;
  333.  
  334. if (decodeParameters) {
  335. value = value.replace(/\+/g, " ");
  336. if (value.indexOf("%") >= 0) {
  337. try {
  338. value = decodeURIComponent(value);
  339. } catch(e) {
  340. errorDecoding = true;
  341. }
  342. }
  343. }
  344. var div = document.createElement("div");
  345. div.className = className;
  346. if (errorDecoding)
  347. div.createChild("span", "error-message").textContent = WebInspector.UIString("(unable to decode value)");
  348. else
  349. div.textContent = value;
  350. return div;
  351. },
  352.  
  353. _refreshURL: function()
  354. {
  355. this._urlTreeElement.title = this._formatHeader(WebInspector.UIString("Request URL"), this._request.url);
  356. },
  357.  
  358. _refreshQueryString: function()
  359. {
  360. var queryString = this._request.queryString();
  361. var queryParameters = this._request.queryParameters;
  362. this._queryStringTreeElement.hidden = !queryParameters;
  363. if (queryParameters)
  364. this._refreshParams(WebInspector.UIString("Query String Parameters"), queryParameters, queryString, this._queryStringTreeElement);
  365. },
  366.  
  367. _refreshUrlFragment: function()
  368. {
  369. var urlFragment = this._request.parsedURL.fragment;
  370. this._urlFragmentTreeElement.hidden = !urlFragment;
  371.  
  372. if (!urlFragment)
  373. return;
  374.  
  375. var sectionTitle = WebInspector.UIString("URL fragment");
  376.  
  377. this._urlFragmentTreeElement.removeChildren();
  378. this._urlFragmentTreeElement.listItemElement.removeChildren();
  379. this._urlFragmentTreeElement.listItemElement.appendChild(document.createTextNode(sectionTitle));
  380.  
  381. var fragmentTreeElement = new TreeElement(null, null, false);
  382. fragmentTreeElement.title = this._formatHeader("#", urlFragment);
  383. fragmentTreeElement.selectable = false;
  384. this._urlFragmentTreeElement.appendChild(fragmentTreeElement);
  385. },
  386.  
  387. _refreshFormData: function()
  388. {
  389. this._formDataTreeElement.hidden = true;
  390. this._requestPayloadTreeElement.hidden = true;
  391.  
  392. var formData = this._request.requestFormData;
  393. if (!formData)
  394. return;
  395.  
  396. var formParameters = this._request.formParameters;
  397. if (formParameters) {
  398. this._formDataTreeElement.hidden = false;
  399. this._refreshParams(WebInspector.UIString("Form Data"), formParameters, formData, this._formDataTreeElement);
  400. } else {
  401. this._requestPayloadTreeElement.hidden = false;
  402. this._populateTreeElementWithSourceText(this._requestPayloadTreeElement, formData)
  403. }
  404. },
  405.  
  406. _populateTreeElementWithSourceText: function(treeElement, sourceText)
  407. {
  408. treeElement.removeChildren();
  409.  
  410. var sourceTreeElement = new TreeElement(null, null, false);
  411. sourceTreeElement.selectable = false;
  412. treeElement.appendChild(sourceTreeElement);
  413.  
  414. var sourceTextElement = document.createElement("span");
  415. sourceTextElement.addStyleClass("header-value");
  416. sourceTextElement.addStyleClass("source-code");
  417. sourceTextElement.textContent = String(sourceText).trim();
  418. sourceTreeElement.listItemElement.appendChild(sourceTextElement);
  419. },
  420.  
  421. _refreshParams: function(title, params, sourceText, paramsTreeElement)
  422. {
  423. paramsTreeElement.removeChildren();
  424.  
  425. paramsTreeElement.listItemElement.removeChildren();
  426. paramsTreeElement.listItemElement.appendChild(document.createTextNode(title));
  427.  
  428. var headerCount = document.createElement("span");
  429. headerCount.addStyleClass("header-count");
  430. headerCount.textContent = WebInspector.UIString(" (%d)", params.length);
  431. paramsTreeElement.listItemElement.appendChild(headerCount);
  432.  
  433. function toggleViewSource()
  434. {
  435. paramsTreeElement._viewSource = !paramsTreeElement._viewSource;
  436. this._refreshParams(title, params, sourceText, paramsTreeElement);
  437. }
  438.  
  439. var viewSourceToggleTitle = paramsTreeElement._viewSource ? WebInspector.UIString("view parsed") : WebInspector.UIString("view source");
  440. var viewSourceToggleButton = this._createToggleButton(viewSourceToggleTitle);
  441. viewSourceToggleButton.addEventListener("click", toggleViewSource.bind(this));
  442. paramsTreeElement.listItemElement.appendChild(viewSourceToggleButton);
  443.  
  444. if (paramsTreeElement._viewSource) {
  445. this._populateTreeElementWithSourceText(paramsTreeElement, sourceText);
  446. return;
  447. }
  448.  
  449. var toggleTitle = this._decodeRequestParameters ? WebInspector.UIString("view URL encoded") : WebInspector.UIString("view decoded");
  450. var toggleButton = this._createToggleButton(toggleTitle);
  451. toggleButton.addEventListener("click", this._toggleURLDecoding.bind(this));
  452. paramsTreeElement.listItemElement.appendChild(toggleButton);
  453.  
  454. for (var i = 0; i < params.length; ++i) {
  455. var paramNameValue = document.createDocumentFragment();
  456. var name = this._formatParameter(params[i].name + ":", "header-name", this._decodeRequestParameters);
  457. var value = this._formatParameter(params[i].value, "header-value source-code", this._decodeRequestParameters);
  458. paramNameValue.appendChild(name);
  459. paramNameValue.appendChild(value);
  460.  
  461. var parmTreeElement = new TreeElement(paramNameValue, null, false);
  462. parmTreeElement.selectable = false;
  463. paramsTreeElement.appendChild(parmTreeElement);
  464. }
  465. },
  466.  
  467. _toggleURLDecoding: function(event)
  468. {
  469. this._decodeRequestParameters = !this._decodeRequestParameters;
  470. this._refreshQueryString();
  471. this._refreshFormData();
  472. },
  473.  
  474. _getHeaderValue: function(headers, key)
  475. {
  476. var lowerKey = key.toLowerCase();
  477. for (var testKey in headers) {
  478. if (testKey.toLowerCase() === lowerKey)
  479. return headers[testKey];
  480. }
  481. },
  482.  
  483. _refreshRequestHeaders: function()
  484. {
  485. var additionalRow = null;
  486. if (typeof this._request.webSocketRequestKey3 !== "undefined")
  487. additionalRow = {name: "(Key3)", value: this._request.webSocketRequestKey3};
  488. if (this._showRequestHeadersText)
  489. this._refreshHeadersText(WebInspector.UIString("Request Headers"), this._request.sortedRequestHeaders, this._request.requestHeadersText, this._requestHeadersTreeElement);
  490. else
  491. this._refreshHeaders(WebInspector.UIString("Request Headers"), this._request.sortedRequestHeaders, additionalRow, this._requestHeadersTreeElement);
  492.  
  493. if (this._request.requestHeadersText) {
  494. var toggleButton = this._createHeadersToggleButton(this._showRequestHeadersText);
  495. toggleButton.addEventListener("click", this._toggleRequestHeadersText.bind(this));
  496. this._requestHeadersTreeElement.listItemElement.appendChild(toggleButton);
  497. }
  498.  
  499. this._refreshFormData();
  500. },
  501.  
  502. _refreshResponseHeaders: function()
  503. {
  504. var additionalRow = null;
  505. if (typeof this._request.webSocketChallengeResponse !== "undefined")
  506. additionalRow = {name: "(Challenge Response)", value: this._request.webSocketChallengeResponse};
  507. if (this._showResponseHeadersText)
  508. this._refreshHeadersText(WebInspector.UIString("Response Headers"), this._request.sortedResponseHeaders, this._request.responseHeadersText, this._responseHeadersTreeElement);
  509. else
  510. this._refreshHeaders(WebInspector.UIString("Response Headers"), this._request.sortedResponseHeaders, additionalRow, this._responseHeadersTreeElement);
  511.  
  512. if (this._request.responseHeadersText) {
  513. var toggleButton = this._createHeadersToggleButton(this._showResponseHeadersText);
  514. toggleButton.addEventListener("click", this._toggleResponseHeadersText.bind(this));
  515. this._responseHeadersTreeElement.listItemElement.appendChild(toggleButton);
  516. }
  517. },
  518.  
  519. _refreshHTTPInformation: function()
  520. {
  521. var requestMethodElement = this._requestMethodTreeElement;
  522. requestMethodElement.hidden = !this._request.statusCode;
  523. var statusCodeElement = this._statusCodeTreeElement;
  524. statusCodeElement.hidden = !this._request.statusCode;
  525.  
  526. if (this._request.statusCode) {
  527. var statusImageSource = "";
  528. if (this._request.statusCode < 300 || this._request.statusCode === 304)
  529. statusImageSource = "Images/successGreenDot.png";
  530. else if (this._request.statusCode < 400)
  531. statusImageSource = "Images/warningOrangeDot.png";
  532. else
  533. statusImageSource = "Images/errorRedDot.png";
  534.  
  535. requestMethodElement.title = this._formatHeader(WebInspector.UIString("Request Method"), this._request.requestMethod);
  536.  
  537. var statusCodeFragment = document.createDocumentFragment();
  538. statusCodeFragment.createChild("div", "header-name").textContent = WebInspector.UIString("Status Code") + ":";
  539.  
  540. var statusCodeImage = statusCodeFragment.createChild("img", "resource-status-image");
  541. statusCodeImage.src = statusImageSource;
  542. statusCodeImage.title = this._request.statusCode + " " + this._request.statusText;
  543. var value = statusCodeFragment.createChild("div", "header-value source-code");
  544. value.textContent = this._request.statusCode + " " + this._request.statusText;
  545. if (this._request.cached)
  546. value.createChild("span", "status-from-cache").textContent = " " + WebInspector.UIString("(from cache)");
  547.  
  548. statusCodeElement.title = statusCodeFragment;
  549. }
  550. },
  551.  
  552. _refreshHeadersTitle: function(title, headersTreeElement, headersLength)
  553. {
  554. headersTreeElement.listItemElement.removeChildren();
  555. headersTreeElement.listItemElement.appendChild(document.createTextNode(title));
  556.  
  557. var headerCount = document.createElement("span");
  558. headerCount.addStyleClass("header-count");
  559. headerCount.textContent = WebInspector.UIString(" (%d)", headersLength);
  560. headersTreeElement.listItemElement.appendChild(headerCount);
  561. },
  562.  
  563. _refreshHeaders: function(title, headers, additionalRow, headersTreeElement)
  564. {
  565. headersTreeElement.removeChildren();
  566.  
  567. var length = headers.length;
  568. this._refreshHeadersTitle(title, headersTreeElement, length);
  569. headersTreeElement.hidden = !length;
  570. for (var i = 0; i < length; ++i) {
  571. var headerTreeElement = new TreeElement(null, null, false);
  572. headerTreeElement.title = this._formatHeader(headers[i].name, headers[i].value);
  573. headerTreeElement.selectable = false;
  574. headersTreeElement.appendChild(headerTreeElement);
  575. }
  576.  
  577. if (additionalRow) {
  578. var headerTreeElement = new TreeElement(null, null, false);
  579. headerTreeElement.title = this._formatHeader(additionalRow.name, additionalRow.value);
  580. headerTreeElement.selectable = false;
  581. headersTreeElement.appendChild(headerTreeElement);
  582. }
  583. },
  584.  
  585. _refreshHeadersText: function(title, headers, headersText, headersTreeElement)
  586. {
  587. this._populateTreeElementWithSourceText(headersTreeElement, headersText);
  588. this._refreshHeadersTitle(title, headersTreeElement, headers.length);
  589. },
  590.  
  591. _toggleRequestHeadersText: function(event)
  592. {
  593. this._showRequestHeadersText = !this._showRequestHeadersText;
  594. this._refreshRequestHeaders();
  595. },
  596.  
  597. _toggleResponseHeadersText: function(event)
  598. {
  599. this._showResponseHeadersText = !this._showResponseHeadersText;
  600. this._refreshResponseHeaders();
  601. },
  602.  
  603. _createToggleButton: function(title)
  604. {
  605. var button = document.createElement("span");
  606. button.addStyleClass("header-toggle");
  607. button.textContent = title;
  608. return button;
  609. },
  610.  
  611. _createHeadersToggleButton: function(isHeadersTextShown)
  612. {
  613. var toggleTitle = isHeadersTextShown ? WebInspector.UIString("view parsed") : WebInspector.UIString("view source");
  614. return this._createToggleButton(toggleTitle);
  615. },
  616.  
  617. __proto__: WebInspector.View.prototype
  618. }
  619. ;
  620.  
  621.  
  622.  
  623. WebInspector.RequestHTMLView = function(request, dataURL)
  624. {
  625. WebInspector.RequestView.call(this, request);
  626. this._dataURL = dataURL;
  627. this.element.addStyleClass("html");
  628. }
  629.  
  630. WebInspector.RequestHTMLView.prototype = {
  631. hasContent: function()
  632. {
  633. return true;
  634. },
  635.  
  636. wasShown: function()
  637. {
  638. this._createIFrame();
  639. },
  640.  
  641. willHide: function(parentElement)
  642. {
  643. this.element.removeChildren();
  644. },
  645.  
  646. _createIFrame: function()
  647. {
  648.  
  649.  
  650. this.element.removeChildren();
  651. var iframe = document.createElement("iframe");
  652. iframe.setAttribute("sandbox", ""); 
  653. iframe.setAttribute("src", this._dataURL);
  654. this.element.appendChild(iframe);
  655. },
  656.  
  657. __proto__: WebInspector.RequestView.prototype
  658. }
  659. ;
  660.  
  661.  
  662.  
  663. WebInspector.RequestJSONView = function(request, parsedJSON)
  664. {
  665. WebInspector.RequestView.call(this, request);
  666. this._parsedJSON = parsedJSON;
  667. this.element.addStyleClass("json");
  668. }
  669.  
  670. WebInspector.RequestJSONView.parseJSON = function(text)
  671. {
  672. var prefix = "";
  673.  
  674.  
  675. var start = /[{[]/.exec(text);
  676. if (start && start.index) {
  677. prefix = text.substring(0, start.index);
  678. text = text.substring(start.index);
  679. }
  680.  
  681. try {
  682. return new WebInspector.ParsedJSON(JSON.parse(text), prefix, "");
  683. } catch (e) {
  684. return;
  685. }
  686. }
  687.  
  688. WebInspector.RequestJSONView.parseJSONP = function(text)
  689. {
  690.  
  691. var start = text.indexOf("(");
  692. var end = text.lastIndexOf(")");
  693. if (start == -1 || end == -1 || end < start)
  694. return;
  695.  
  696. var prefix = text.substring(0, start + 1);
  697. var suffix = text.substring(end);
  698. text = text.substring(start + 1, end);
  699.  
  700. try {
  701. return new WebInspector.ParsedJSON(JSON.parse(text), prefix, suffix);
  702. } catch (e) {
  703. return;
  704. }
  705. }
  706.  
  707. WebInspector.RequestJSONView.prototype = {
  708. hasContent: function()
  709. {
  710. return true;
  711. },
  712.  
  713. wasShown: function()
  714. {
  715. this._initialize();
  716. },
  717.  
  718. _initialize: function()
  719. {
  720. if (this._initialized)
  721. return;
  722. this._initialized = true;
  723.  
  724. var obj = WebInspector.RemoteObject.fromLocalObject(this._parsedJSON.data);
  725. var title = this._parsedJSON.prefix + obj.description + this._parsedJSON.suffix;
  726. var section = new WebInspector.ObjectPropertiesSection(obj, title);
  727. section.expand();
  728. section.editable = false;
  729. this.element.appendChild(section.element);
  730. },
  731.  
  732. __proto__: WebInspector.RequestView.prototype
  733. }
  734.  
  735.  
  736. WebInspector.ParsedJSON = function(data, prefix, suffix)
  737. {
  738. this.data = data;
  739. this.prefix = prefix;
  740. this.suffix = suffix;
  741. }
  742. ;
  743.  
  744.  
  745.  
  746. WebInspector.RequestPreviewView = function(request, responseView)
  747. {
  748. WebInspector.RequestContentView.call(this, request);
  749. this._responseView = responseView;
  750. }
  751.  
  752. WebInspector.RequestPreviewView.prototype = {
  753. contentLoaded: function()
  754. {
  755. if (!this.request.content) {
  756. if (!this._emptyView) {
  757. this._emptyView = this._createEmptyView();
  758. this._emptyView.show(this.element);
  759. this.innerView = this._emptyView;
  760. }
  761. } else {
  762. if (this._emptyView) {
  763. this._emptyView.detach();
  764. delete this._emptyView;
  765. }
  766.  
  767. if (!this._previewView)
  768. this._previewView = this._createPreviewView();
  769. this._previewView.show(this.element);
  770. this.innerView = this._previewView;
  771. }
  772. },
  773.  
  774. _createEmptyView: function()
  775. {
  776. return new WebInspector.EmptyView(WebInspector.UIString("This request has no preview available."));
  777. },
  778.  
  779. _createPreviewView: function()
  780. {
  781. if (this.request.content) {
  782. if (this.request.hasErrorStatusCode() || (this.request.type === WebInspector.resourceTypes.XHR && this.request.mimeType === "text/html")) {
  783. var dataURL = this.request.asDataURL();
  784. if (dataURL !== null)
  785. return new WebInspector.RequestHTMLView(this.request, dataURL);
  786. }
  787. }
  788.  
  789. if (this.request.type === WebInspector.resourceTypes.XHR && this.request.content) {
  790. var parsedJSON = WebInspector.RequestJSONView.parseJSON(this.request.content);
  791. if (parsedJSON)
  792. return new WebInspector.RequestJSONView(this.request, parsedJSON);
  793. }
  794.  
  795. if (this.request.content && this.request.type === WebInspector.resourceTypes.Script && this.request.mimeType === "application/json") {
  796. var parsedJSONP = WebInspector.RequestJSONView.parseJSONP(this.request.content);
  797. if (parsedJSONP)
  798. return new WebInspector.RequestJSONView(this.request, parsedJSONP);
  799. }
  800.  
  801. if (this._responseView.sourceView)
  802. return this._responseView.sourceView;
  803.  
  804. if (this.request.type === WebInspector.resourceTypes.Other)
  805. return this._createEmptyView();
  806.  
  807. return WebInspector.RequestView.nonSourceViewForRequest(this.request);
  808. },
  809.  
  810. __proto__: WebInspector.RequestContentView.prototype
  811. }
  812. ;
  813.  
  814.  
  815.  
  816. WebInspector.RequestResponseView = function(request)
  817. {
  818. WebInspector.RequestContentView.call(this, request);
  819. }
  820.  
  821. WebInspector.RequestResponseView.prototype = {
  822. get sourceView()
  823. {
  824. if (!this._sourceView && WebInspector.RequestView.hasTextContent(this.request))
  825. this._sourceView = new WebInspector.ResourceSourceFrame(this.request);
  826. return this._sourceView;
  827. },
  828.  
  829. contentLoaded: function()
  830. {
  831. if (!this.request.content || !this.sourceView) {
  832. if (!this._emptyView) {
  833. this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("This request has no response data available."));
  834. this._emptyView.show(this.element);
  835. this.innerView = this._emptyView;
  836. }
  837. } else {
  838. if (this._emptyView) {
  839. this._emptyView.detach();
  840. delete this._emptyView;
  841. }
  842.  
  843. this.sourceView.show(this.element);
  844. this.innerView = this.sourceView;
  845. }
  846. },
  847.  
  848. __proto__: WebInspector.RequestContentView.prototype
  849. }
  850. ;
  851.  
  852.  
  853.  
  854. WebInspector.RequestTimingView = function(request)
  855. {
  856. WebInspector.View.call(this);
  857. this.element.addStyleClass("resource-timing-view");
  858.  
  859. this._request = request;
  860.  
  861. request.addEventListener(WebInspector.NetworkRequest.Events.TimingChanged, this._refresh, this);
  862. }
  863.  
  864. WebInspector.RequestTimingView.prototype = {
  865. wasShown: function()
  866. {
  867. if (!this._request.timing) {
  868. if (!this._emptyView) {
  869. this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("This request has no detailed timing info."));
  870. this._emptyView.show(this.element);
  871. this.innerView = this._emptyView;
  872. }
  873. return;
  874. }
  875.  
  876. if (this._emptyView) {
  877. this._emptyView.detach();
  878. delete this._emptyView;
  879. }
  880.  
  881. this._refresh();
  882. },
  883.  
  884. _refresh: function()
  885. {
  886. if (this._tableElement)
  887. this._tableElement.parentElement.removeChild(this._tableElement);
  888.  
  889. this._tableElement = WebInspector.RequestTimingView.createTimingTable(this._request);
  890. this.element.appendChild(this._tableElement);
  891. },
  892.  
  893. __proto__: WebInspector.View.prototype
  894. }
  895.  
  896.  
  897. WebInspector.RequestTimingView.createTimingTable = function(request)
  898. {
  899. var tableElement = document.createElement("table");
  900. var rows = [];
  901.  
  902. function addRow(title, className, start, end)
  903. {
  904. var row = {};
  905. row.title = title;
  906. row.className = className;
  907. row.start = start;
  908. row.end = end;
  909. rows.push(row);
  910. }
  911.  
  912. if (request.timing.proxyStart !== -1)
  913. addRow(WebInspector.UIString("Proxy"), "proxy", request.timing.proxyStart, request.timing.proxyEnd);
  914.  
  915. if (request.timing.dnsStart !== -1)
  916. addRow(WebInspector.UIString("DNS Lookup"), "dns", request.timing.dnsStart, request.timing.dnsEnd);
  917.  
  918. if (request.timing.connectStart !== -1) {
  919. if (request.connectionReused)
  920. addRow(WebInspector.UIString("Blocking"), "connecting", request.timing.connectStart, request.timing.connectEnd);
  921. else {
  922. var connectStart = request.timing.connectStart;
  923.  
  924. if (request.timing.dnsStart !== -1)
  925. connectStart += request.timing.dnsEnd - request.timing.dnsStart;
  926. addRow(WebInspector.UIString("Connecting"), "connecting", connectStart, request.timing.connectEnd);
  927. }
  928. }
  929.  
  930. if (request.timing.sslStart !== -1)
  931. addRow(WebInspector.UIString("SSL"), "ssl", request.timing.sslStart, request.timing.sslEnd);
  932.  
  933. var sendStart = request.timing.sendStart;
  934. if (request.timing.sslStart !== -1)
  935. sendStart += request.timing.sslEnd - request.timing.sslStart;
  936.  
  937. addRow(WebInspector.UIString("Sending"), "sending", request.timing.sendStart, request.timing.sendEnd);
  938. addRow(WebInspector.UIString("Waiting"), "waiting", request.timing.sendEnd, request.timing.receiveHeadersEnd);
  939. addRow(WebInspector.UIString("Receiving"), "receiving", (request.responseReceivedTime - request.timing.requestTime) * 1000, (request.endTime - request.timing.requestTime) * 1000);
  940.  
  941. const chartWidth = 200;
  942. var total = (request.endTime - request.timing.requestTime) * 1000;
  943. var scale = chartWidth / total;
  944.  
  945. for (var i = 0; i < rows.length; ++i) {
  946. var tr = document.createElement("tr");
  947. tableElement.appendChild(tr);
  948.  
  949. var td = document.createElement("td");
  950. td.textContent = rows[i].title;
  951. tr.appendChild(td);
  952.  
  953. td = document.createElement("td");
  954. td.width = chartWidth + "px";
  955.  
  956. var row = document.createElement("div");
  957. row.className = "network-timing-row";
  958. td.appendChild(row);
  959.  
  960. var bar = document.createElement("span");
  961. bar.className = "network-timing-bar " + rows[i].className;
  962. bar.style.left = scale * rows[i].start + "px";
  963. bar.style.right = scale * (total - rows[i].end) + "px";
  964. bar.style.backgroundColor = rows[i].color;
  965. bar.textContent = "\u200B"; 
  966. row.appendChild(bar);
  967.  
  968. var title = document.createElement("span");
  969. title.className = "network-timing-bar-title";
  970. if (total - rows[i].end < rows[i].start)
  971. title.style.right = (scale * (total - rows[i].end) + 3) + "px";
  972. else
  973. title.style.left = (scale * rows[i].start + 3) + "px";
  974. title.textContent = Number.secondsToString((rows[i].end - rows[i].start) / 1000);
  975. row.appendChild(title);
  976.  
  977. tr.appendChild(td);
  978. }
  979. return tableElement;
  980. }
  981. ;
  982.  
  983.  
  984.  
  985. WebInspector.ResourceWebSocketFrameView = function(resource)
  986. {
  987. WebInspector.View.call(this);
  988. this.element.addStyleClass("resource-websocket");
  989. this.resource = resource;
  990. this.element.removeChildren();
  991.  
  992. var dataGrid = new WebInspector.DataGrid({
  993. data: {title: WebInspector.UIString("Data"), sortable: false},
  994. length: {title: WebInspector.UIString("Length"), sortable: false, aligned: "right", width: "50px"},
  995. time: {title: WebInspector.UIString("Time"), width: "70px"}
  996. });
  997.  
  998. var frames = this.resource.frames();
  999. for (var i = 0; i < frames.length; i++) {
  1000. var payload = frames[i];
  1001.  
  1002. var date = new Date(payload.time * 1000);
  1003. var row = {
  1004. data: "",
  1005. length: payload.payloadData.length.toString(),
  1006. time: date.toLocaleTimeString()
  1007. };
  1008.  
  1009. var rowClass = "";
  1010. if (payload.errorMessage) {
  1011. rowClass = "error";
  1012. row.data = payload.errorMessage;
  1013. } else if (payload.opcode == WebInspector.ResourceWebSocketFrameView.OpCodes.TextFrame) {
  1014. if (payload.sent)
  1015. rowClass = "outcoming";
  1016.  
  1017. row.data = payload.payloadData;
  1018. } else {
  1019. rowClass = "opcode";
  1020. var opcodeMeaning = "";
  1021. switch (payload.opcode) {
  1022. case WebInspector.ResourceWebSocketFrameView.OpCodes.ContinuationFrame:
  1023. opcodeMeaning = WebInspector.UIString("Continuation Frame");
  1024. break;
  1025. case WebInspector.ResourceWebSocketFrameView.OpCodes.BinaryFrame:
  1026. opcodeMeaning = WebInspector.UIString("Binary Frame");
  1027. break;
  1028. case WebInspector.ResourceWebSocketFrameView.OpCodes.ConnectionCloseFrame:
  1029. opcodeMeaning = WebInspector.UIString("Connection Close Frame");
  1030. break;
  1031. case WebInspector.ResourceWebSocketFrameView.OpCodes.PingFrame:
  1032. opcodeMeaning = WebInspector.UIString("Ping Frame");
  1033. break;
  1034. case WebInspector.ResourceWebSocketFrameView.OpCodes.PongFrame:
  1035. opcodeMeaning = WebInspector.UIString("Pong Frame");
  1036. break;
  1037. }
  1038. row.data = WebInspector.UIString("%s (Opcode %d%s)", opcodeMeaning, payload.opcode, (payload.mask ? ", mask" : ""));
  1039. }
  1040.  
  1041. var node = new WebInspector.DataGridNode(row, false);
  1042. dataGrid.rootNode().appendChild(node);
  1043.  
  1044. if (rowClass)
  1045. node.element.classList.add("resource-websocket-row-" + rowClass);
  1046.  
  1047. }
  1048. dataGrid.show(this.element);
  1049. }
  1050.  
  1051. WebInspector.ResourceWebSocketFrameView.OpCodes = {
  1052. ContinuationFrame: 0,
  1053. TextFrame: 1,
  1054. BinaryFrame: 2,
  1055. ConnectionCloseFrame: 8,
  1056. PingFrame: 9,
  1057. PongFrame: 10
  1058. };
  1059.  
  1060. WebInspector.ResourceWebSocketFrameView.prototype = {
  1061. __proto__: WebInspector.View.prototype
  1062. }
  1063. ;
  1064.  
  1065.  
  1066. WebInspector.NetworkLogView = function()
  1067. {
  1068. WebInspector.View.call(this);
  1069. this.registerRequiredCSS("networkLogView.css");
  1070.  
  1071. this._allowRequestSelection = false;
  1072. this._requests = [];
  1073. this._requestsById = {};
  1074. this._requestsByURL = {};
  1075. this._staleRequests = {};
  1076. this._requestGridNodes = {};
  1077. this._lastRequestGridNodeId = 0;
  1078. this._mainRequestLoadTime = -1;
  1079. this._mainRequestDOMContentTime = -1;
  1080. this._hiddenCategories = {};
  1081. this._matchedRequests = [];
  1082. this._filteredOutRequests = new Map();
  1083.  
  1084. this._matchedRequestsMap = {};
  1085. this._currentMatchedRequestIndex = -1;
  1086.  
  1087. this._createStatusbarButtons();
  1088. this._createStatusBarItems();
  1089. this._linkifier = new WebInspector.Linkifier();
  1090.  
  1091. WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
  1092. WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdated, this._onRequestUpdated, this);
  1093. WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestUpdated, this);
  1094.  
  1095. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
  1096. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.OnLoad, this._onLoadEventFired, this);
  1097. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._domContentLoadedEventFired, this);
  1098.  
  1099. this._initializeView();
  1100. function onCanClearBrowserCache(error, result)
  1101. {
  1102. this._canClearBrowserCache = result;
  1103. }
  1104. NetworkAgent.canClearBrowserCache(onCanClearBrowserCache.bind(this));
  1105.  
  1106. function onCanClearBrowserCookies(error, result)
  1107. {
  1108. this._canClearBrowserCookies = result;
  1109. }
  1110. NetworkAgent.canClearBrowserCookies(onCanClearBrowserCookies.bind(this));
  1111.  
  1112. WebInspector.networkLog.requests.forEach(this._appendRequest.bind(this));
  1113. }
  1114.  
  1115. WebInspector.NetworkLogView.prototype = {
  1116. _initializeView: function()
  1117. {
  1118. this.element.id = "network-container";
  1119.  
  1120. this._createSortingFunctions();
  1121. this._createTable();
  1122. this._createTimelineGrid();
  1123. this._createSummaryBar();
  1124.  
  1125. if (!this.useLargeRows)
  1126. this._setLargerRequests(this.useLargeRows);
  1127.  
  1128. this._allowPopover = true;
  1129. this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this));
  1130.  
  1131. this._popoverHelper.setTimeout(100);
  1132.  
  1133. this.calculator = new WebInspector.NetworkTransferTimeCalculator();
  1134. this._filter(this._filterAllElement, false);
  1135.  
  1136. this.switchToDetailedView();
  1137. },
  1138.  
  1139. get statusBarItems()
  1140. {
  1141. return [this._largerRequestsButton.element, this._preserveLogToggle.element, this._clearButton.element, this._filterBarElement, this._progressBarContainer];
  1142. },
  1143.  
  1144. get useLargeRows()
  1145. {
  1146. return WebInspector.settings.resourcesLargeRows.get();
  1147. },
  1148.  
  1149. set allowPopover(flag)
  1150. {
  1151. this._allowPopover = flag;
  1152. },
  1153.  
  1154. elementsToRestoreScrollPositionsFor: function()
  1155. {
  1156. if (!this._dataGrid) 
  1157. return [];
  1158. return [this._dataGrid.scrollContainer];
  1159. },
  1160.  
  1161. onResize: function()
  1162. {
  1163. this._updateOffscreenRows();
  1164. },
  1165.  
  1166. _createTimelineGrid: function()
  1167. {
  1168. this._timelineGrid = new WebInspector.TimelineGrid();
  1169. this._timelineGrid.element.addStyleClass("network-timeline-grid");
  1170. this._dataGrid.element.appendChild(this._timelineGrid.element);
  1171. },
  1172.  
  1173. _createTable: function()
  1174. {
  1175. var columns = {name: {}, method: {}, status: {}, type: {}, initiator: {}, size: {}, time: {}, timeline: {}};
  1176.  
  1177. columns.name.titleDOMFragment = this._makeHeaderFragment(WebInspector.UIString("Name"), WebInspector.UIString("Path"));
  1178. columns.name.sortable = true;
  1179. columns.name.width = "20%";
  1180. columns.name.disclosure = true;
  1181.  
  1182. columns.method.title = WebInspector.UIString("Method");
  1183. columns.method.sortable = true;
  1184. columns.method.width = "6%";
  1185.  
  1186. columns.status.titleDOMFragment = this._makeHeaderFragment(WebInspector.UIString("Status"), WebInspector.UIString("Text"));
  1187. columns.status.sortable = true;
  1188. columns.status.width = "6%";
  1189.  
  1190. columns.type.title = WebInspector.UIString("Type");
  1191. columns.type.sortable = true;
  1192. columns.type.width = "6%";
  1193.  
  1194. columns.initiator.title = WebInspector.UIString("Initiator");
  1195. columns.initiator.sortable = true;
  1196. columns.initiator.width = "10%";
  1197.  
  1198. columns.size.titleDOMFragment = this._makeHeaderFragment(WebInspector.UIString("Size"), WebInspector.UIString("Content"));
  1199. columns.size.sortable = true;
  1200. columns.size.width = "6%";
  1201. columns.size.aligned = "right";
  1202.  
  1203. columns.time.titleDOMFragment = this._makeHeaderFragment(WebInspector.UIString("Time"), WebInspector.UIString("Latency"));
  1204. columns.time.sortable = true;
  1205. columns.time.width = "6%";
  1206. columns.time.aligned = "right";
  1207.  
  1208. columns.timeline.title = "";
  1209. columns.timeline.sortable = false;
  1210. columns.timeline.width = "40%";
  1211. columns.timeline.sort = "ascending";
  1212.  
  1213. this._dataGrid = new WebInspector.DataGrid(columns);
  1214. this._dataGrid.resizeMethod = WebInspector.DataGrid.ResizeMethod.Last;
  1215. this._dataGrid.element.addStyleClass("network-log-grid");
  1216. this._dataGrid.element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
  1217. this._dataGrid.show(this.element);
  1218.  
  1219.  
  1220. this._dataGrid.addEventListener("sorting changed", this._sortItems, this);
  1221. this._dataGrid.addEventListener("width changed", this._updateDividersIfNeeded, this);
  1222. this._dataGrid.scrollContainer.addEventListener("scroll", this._updateOffscreenRows.bind(this));
  1223.  
  1224. this._patchTimelineHeader();
  1225. },
  1226.  
  1227. _makeHeaderFragment: function(title, subtitle)
  1228. {
  1229. var fragment = document.createDocumentFragment();
  1230. fragment.appendChild(document.createTextNode(title));
  1231. var subtitleDiv = document.createElement("div");
  1232. subtitleDiv.className = "network-header-subtitle";
  1233. subtitleDiv.textContent = subtitle;
  1234. fragment.appendChild(subtitleDiv);
  1235. return fragment;
  1236. },
  1237.  
  1238. _patchTimelineHeader: function()
  1239. {
  1240. var timelineSorting = document.createElement("select");
  1241.  
  1242. var option = document.createElement("option");
  1243. option.value = "startTime";
  1244. option.label = WebInspector.UIString("Timeline");
  1245. timelineSorting.appendChild(option);
  1246.  
  1247. option = document.createElement("option");
  1248. option.value = "startTime";
  1249. option.label = WebInspector.UIString("Start Time");
  1250. timelineSorting.appendChild(option);
  1251.  
  1252. option = document.createElement("option");
  1253. option.value = "responseTime";
  1254. option.label = WebInspector.UIString("Response Time");
  1255. timelineSorting.appendChild(option);
  1256.  
  1257. option = document.createElement("option");
  1258. option.value = "endTime";
  1259. option.label = WebInspector.UIString("End Time");
  1260. timelineSorting.appendChild(option);
  1261.  
  1262. option = document.createElement("option");
  1263. option.value = "duration";
  1264. option.label = WebInspector.UIString("Duration");
  1265. timelineSorting.appendChild(option);
  1266.  
  1267. option = document.createElement("option");
  1268. option.value = "latency";
  1269. option.label = WebInspector.UIString("Latency");
  1270. timelineSorting.appendChild(option);
  1271.  
  1272. var header = this._dataGrid.headerTableHeader("timeline");
  1273. header.replaceChild(timelineSorting, header.firstChild);
  1274.  
  1275. timelineSorting.addEventListener("click", function(event) { event.consume() }, false);
  1276. timelineSorting.addEventListener("change", this._sortByTimeline.bind(this), false);
  1277. this._timelineSortSelector = timelineSorting;
  1278. },
  1279.  
  1280. _createSortingFunctions: function()
  1281. {
  1282. this._sortingFunctions = {};
  1283. this._sortingFunctions.name = WebInspector.NetworkDataGridNode.NameComparator;
  1284. this._sortingFunctions.method = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "method", false);
  1285. this._sortingFunctions.status = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "statusCode", false);
  1286. this._sortingFunctions.type = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "mimeType", false);
  1287. this._sortingFunctions.initiator = WebInspector.NetworkDataGridNode.InitiatorComparator;
  1288. this._sortingFunctions.size = WebInspector.NetworkDataGridNode.SizeComparator;
  1289. this._sortingFunctions.time = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "duration", false);
  1290. this._sortingFunctions.timeline = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "startTime", false);
  1291. this._sortingFunctions.startTime = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "startTime", false);
  1292. this._sortingFunctions.endTime = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "endTime", false);
  1293. this._sortingFunctions.responseTime = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "responseReceivedTime", false);
  1294. this._sortingFunctions.duration = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "duration", true);
  1295. this._sortingFunctions.latency = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "latency", true);
  1296.  
  1297. var timeCalculator = new WebInspector.NetworkTransferTimeCalculator();
  1298. var durationCalculator = new WebInspector.NetworkTransferDurationCalculator();
  1299.  
  1300. this._calculators = {};
  1301. this._calculators.timeline = timeCalculator;
  1302. this._calculators.startTime = timeCalculator;
  1303. this._calculators.endTime = timeCalculator;
  1304. this._calculators.responseTime = timeCalculator;
  1305. this._calculators.duration = durationCalculator;
  1306. this._calculators.latency = durationCalculator;
  1307. },
  1308.  
  1309. _sortItems: function()
  1310. {
  1311. this._removeAllNodeHighlights();
  1312. var columnIdentifier = this._dataGrid.sortColumnIdentifier;
  1313. if (columnIdentifier === "timeline") {
  1314. this._sortByTimeline();
  1315. return;
  1316. }
  1317. var sortingFunction = this._sortingFunctions[columnIdentifier];
  1318. if (!sortingFunction)
  1319. return;
  1320.  
  1321. this._dataGrid.sortNodes(sortingFunction, this._dataGrid.sortOrder === "descending");
  1322. this._timelineSortSelector.selectedIndex = 0;
  1323. this._updateOffscreenRows();
  1324.  
  1325. this.searchCanceled();
  1326. },
  1327.  
  1328. _sortByTimeline: function()
  1329. {
  1330. this._removeAllNodeHighlights();
  1331. var selectedIndex = this._timelineSortSelector.selectedIndex;
  1332. if (!selectedIndex)
  1333. selectedIndex = 1; 
  1334. var selectedOption = this._timelineSortSelector[selectedIndex];
  1335. var value = selectedOption.value;
  1336.  
  1337. var sortingFunction = this._sortingFunctions[value];
  1338. this._dataGrid.sortNodes(sortingFunction);
  1339. this.calculator = this._calculators[value];
  1340. if (this.calculator.startAtZero)
  1341. this._timelineGrid.hideEventDividers();
  1342. else
  1343. this._timelineGrid.showEventDividers();
  1344. this._dataGrid.markColumnAsSortedBy("timeline", "ascending");
  1345. this._updateOffscreenRows();
  1346. },
  1347.  
  1348. _createStatusBarItems: function()
  1349. {
  1350. var filterBarElement = document.createElement("div");
  1351. filterBarElement.className = "scope-bar status-bar-item";
  1352.  
  1353.  
  1354. function createFilterElement(typeName, label)
  1355. {
  1356. var categoryElement = document.createElement("li");
  1357. categoryElement.typeName = typeName;
  1358. categoryElement.className = typeName;
  1359. categoryElement.appendChild(document.createTextNode(label));
  1360. categoryElement.addEventListener("click", this._updateFilter.bind(this), false);
  1361. filterBarElement.appendChild(categoryElement);
  1362.  
  1363. return categoryElement;
  1364. }
  1365.  
  1366. this._filterAllElement = createFilterElement.call(this, "all", WebInspector.UIString("All"));
  1367.  
  1368.  
  1369. var dividerElement = document.createElement("div");
  1370. dividerElement.addStyleClass("scope-bar-divider");
  1371. filterBarElement.appendChild(dividerElement);
  1372.  
  1373. for (var typeId in WebInspector.resourceTypes) {
  1374. var type = WebInspector.resourceTypes[typeId];
  1375. createFilterElement.call(this, type.name(), type.categoryTitle());
  1376. }
  1377. this._filterBarElement = filterBarElement;
  1378. this._progressBarContainer = document.createElement("div");
  1379. this._progressBarContainer.className = "status-bar-item";
  1380. },
  1381.  
  1382. _createSummaryBar: function()
  1383. {
  1384. var tbody = this._dataGrid.dataTableBody;
  1385. var tfoot = document.createElement("tfoot");
  1386. var tr = tfoot.createChild("tr", "revealed network-summary-bar");
  1387. var td = tr.createChild("td");
  1388. td.setAttribute("colspan", 7);
  1389. tbody.parentNode.insertBefore(tfoot, tbody);
  1390. this._summaryBarElement = td;
  1391. },
  1392.  
  1393. _updateSummaryBar: function()
  1394. {
  1395. var requestsNumber = this._requests.length;
  1396.  
  1397. if (!requestsNumber) {
  1398. if (this._summaryBarElement._isDisplayingWarning)
  1399. return;
  1400. this._summaryBarElement._isDisplayingWarning = true;
  1401.  
  1402. var img = document.createElement("img");
  1403. img.src = "Images/warningIcon.png";
  1404. this._summaryBarElement.removeChildren();
  1405. this._summaryBarElement.appendChild(img);
  1406. this._summaryBarElement.appendChild(document.createTextNode(
  1407. WebInspector.UIString("No requests captured. Reload the page to see detailed information on the network activity.")));
  1408. return;
  1409. }
  1410. delete this._summaryBarElement._isDisplayingWarning;
  1411.  
  1412. var transferSize = 0;
  1413. var selectedRequestsNumber = 0;
  1414. var selectedTransferSize = 0;
  1415. var baseTime = -1;
  1416. var maxTime = -1;
  1417. for (var i = 0; i < this._requests.length; ++i) {
  1418. var request = this._requests[i];
  1419. var requestTransferSize = (request.cached || !request.transferSize) ? 0 : request.transferSize;
  1420. transferSize += requestTransferSize;
  1421. if ((!this._hiddenCategories.all || !this._hiddenCategories[request.type.name()]) && !this._filteredOutRequests.get(request)) {
  1422. selectedRequestsNumber++;
  1423. selectedTransferSize += requestTransferSize;
  1424. }
  1425. if (request.url === WebInspector.inspectedPageURL)
  1426. baseTime = request.startTime;
  1427. if (request.endTime > maxTime)
  1428. maxTime = request.endTime;
  1429. }
  1430. var text = "";
  1431. if (selectedRequestsNumber !== requestsNumber) {
  1432. text += String.sprintf(WebInspector.UIString("%d / %d requests"), selectedRequestsNumber, requestsNumber);
  1433. text += "  \u2758  " + String.sprintf(WebInspector.UIString("%s / %s transferred"), Number.bytesToString(selectedTransferSize), Number.bytesToString(transferSize));
  1434. } else {
  1435. text += String.sprintf(WebInspector.UIString("%d requests"), requestsNumber);
  1436. text += "  \u2758  " + String.sprintf(WebInspector.UIString("%s transferred"), Number.bytesToString(transferSize));
  1437. }
  1438. if (baseTime !== -1 && this._mainRequestLoadTime !== -1 && this._mainRequestDOMContentTime !== -1 && this._mainRequestDOMContentTime > baseTime) {
  1439. text += "  \u2758  " + String.sprintf(WebInspector.UIString("%s (onload: %s, DOMContentLoaded: %s)"),
  1440. Number.secondsToString(maxTime - baseTime),
  1441. Number.secondsToString(this._mainRequestLoadTime - baseTime),
  1442. Number.secondsToString(this._mainRequestDOMContentTime - baseTime));
  1443. }
  1444. this._summaryBarElement.textContent = text;
  1445. },
  1446.  
  1447. _showCategory: function(typeName)
  1448. {
  1449. this._dataGrid.element.addStyleClass("filter-" + typeName);
  1450. delete this._hiddenCategories[typeName];
  1451. },
  1452.  
  1453. _hideCategory: function(typeName)
  1454. {
  1455. this._dataGrid.element.removeStyleClass("filter-" + typeName);
  1456. this._hiddenCategories[typeName] = true;
  1457. },
  1458.  
  1459. _updateFilter: function(e)
  1460. {
  1461. this._removeAllNodeHighlights();
  1462. var isMac = WebInspector.isMac();
  1463. var selectMultiple = false;
  1464. if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
  1465. selectMultiple = true;
  1466. if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey)
  1467. selectMultiple = true;
  1468.  
  1469. this._filter(e.target, selectMultiple);
  1470. this.searchCanceled();
  1471. this._updateSummaryBar();
  1472. },
  1473.  
  1474. _filter: function(target, selectMultiple)
  1475. {
  1476. function unselectAll()
  1477. {
  1478. for (var i = 0; i < this._filterBarElement.childNodes.length; ++i) {
  1479. var child = this._filterBarElement.childNodes[i];
  1480. if (!child.typeName)
  1481. continue;
  1482.  
  1483. child.removeStyleClass("selected");
  1484. this._hideCategory(child.typeName);
  1485. }
  1486. }
  1487.  
  1488. if (target === this._filterAllElement) {
  1489. if (target.hasStyleClass("selected")) {
  1490.  
  1491. return;
  1492. }
  1493.  
  1494.  
  1495. unselectAll.call(this);
  1496. } else {
  1497.  
  1498. if (this._filterAllElement.hasStyleClass("selected")) {
  1499. this._filterAllElement.removeStyleClass("selected");
  1500. this._hideCategory("all");
  1501. }
  1502. }
  1503.  
  1504. if (!selectMultiple) {
  1505.  
  1506.  
  1507. unselectAll.call(this);
  1508.  
  1509. target.addStyleClass("selected");
  1510. this._showCategory(target.typeName);
  1511. this._updateOffscreenRows();
  1512. return;
  1513. }
  1514.  
  1515. if (target.hasStyleClass("selected")) {
  1516.  
  1517.  
  1518. target.removeStyleClass("selected");
  1519. this._hideCategory(target.typeName);
  1520. } else {
  1521.  
  1522.  
  1523. target.addStyleClass("selected");
  1524. this._showCategory(target.typeName);
  1525. }
  1526. this._updateOffscreenRows();
  1527. },
  1528.  
  1529. _defaultRefreshDelay: 500,
  1530.  
  1531. _scheduleRefresh: function()
  1532. {
  1533. if (this._needsRefresh)
  1534. return;
  1535.  
  1536. this._needsRefresh = true;
  1537.  
  1538. if (this.isShowing() && !this._refreshTimeout)
  1539. this._refreshTimeout = setTimeout(this.refresh.bind(this), this._defaultRefreshDelay);
  1540. },
  1541.  
  1542. _updateDividersIfNeeded: function()
  1543. {
  1544. if (!this._dataGrid)
  1545. return;
  1546. var timelineColumn = this._dataGrid.columns.timeline;
  1547. for (var i = 0; i < this._dataGrid.resizers.length; ++i) {
  1548. if (timelineColumn.ordinal === this._dataGrid.resizers[i].rightNeighboringColumnID) {
  1549.  
  1550. this._timelineGrid.element.style.left = this._dataGrid.resizers[i].style.left;
  1551. this._timelineGrid.element.style.right = "18px";
  1552. }
  1553. }
  1554.  
  1555. var proceed = true;
  1556. if (!this.isShowing()) {
  1557. this._scheduleRefresh();
  1558. proceed = false;
  1559. } else {
  1560. this.calculator.setDisplayWindow(this._timelineGrid.element.clientWidth);
  1561. proceed = this._timelineGrid.updateDividers(this.calculator);
  1562. }
  1563. if (!proceed)
  1564. return;
  1565.  
  1566. if (this.calculator.startAtZero || !this.calculator.computePercentageFromEventTime) {
  1567.  
  1568.  
  1569.  
  1570.  
  1571.  
  1572.  
  1573. return;
  1574. }
  1575.  
  1576. this._timelineGrid.removeEventDividers();
  1577. if (this._mainRequestLoadTime !== -1) {
  1578. var percent = this.calculator.computePercentageFromEventTime(this._mainRequestLoadTime);
  1579.  
  1580. var loadDivider = document.createElement("div");
  1581. loadDivider.className = "network-event-divider network-red-divider";
  1582.  
  1583. var loadDividerPadding = document.createElement("div");
  1584. loadDividerPadding.className = "network-event-divider-padding";
  1585. loadDividerPadding.title = WebInspector.UIString("Load event fired");
  1586. loadDividerPadding.appendChild(loadDivider);
  1587. loadDividerPadding.style.left = percent + "%";
  1588. this._timelineGrid.addEventDivider(loadDividerPadding);
  1589. }
  1590.  
  1591. if (this._mainRequestDOMContentTime !== -1) {
  1592. var percent = this.calculator.computePercentageFromEventTime(this._mainRequestDOMContentTime);
  1593.  
  1594. var domContentDivider = document.createElement("div");
  1595. domContentDivider.className = "network-event-divider network-blue-divider";
  1596.  
  1597. var domContentDividerPadding = document.createElement("div");
  1598. domContentDividerPadding.className = "network-event-divider-padding";
  1599. domContentDividerPadding.title = WebInspector.UIString("DOMContent event fired");
  1600. domContentDividerPadding.appendChild(domContentDivider);
  1601. domContentDividerPadding.style.left = percent + "%";
  1602. this._timelineGrid.addEventDivider(domContentDividerPadding);
  1603. }
  1604. },
  1605.  
  1606. _refreshIfNeeded: function()
  1607. {
  1608. if (this._needsRefresh)
  1609. this.refresh();
  1610. },
  1611.  
  1612. _invalidateAllItems: function()
  1613. {
  1614. for (var i = 0; i < this._requests.length; ++i) {
  1615. var request = this._requests[i];
  1616. this._staleRequests[request.requestId] = request;
  1617. }
  1618. },
  1619.  
  1620. get calculator()
  1621. {
  1622. return this._calculator;
  1623. },
  1624.  
  1625. set calculator(x)
  1626. {
  1627. if (!x || this._calculator === x)
  1628. return;
  1629.  
  1630. this._calculator = x;
  1631. this._calculator.reset();
  1632.  
  1633. this._invalidateAllItems();
  1634. this.refresh();
  1635. },
  1636.  
  1637. _requestGridNode: function(request)
  1638. {
  1639. return this._requestGridNodes[request.__gridNodeId];
  1640. },
  1641.  
  1642. _createRequestGridNode: function(request)
  1643. {
  1644. var node = new WebInspector.NetworkDataGridNode(this, request);
  1645. request.__gridNodeId = this._lastRequestGridNodeId++;
  1646. this._requestGridNodes[request.__gridNodeId] = node;
  1647. return node;
  1648. },
  1649.  
  1650. _createStatusbarButtons: function()
  1651. {
  1652. this._preserveLogToggle = new WebInspector.StatusBarButton(WebInspector.UIString("Preserve Log upon Navigation"), "record-profile-status-bar-item");
  1653. this._preserveLogToggle.addEventListener("click", this._onPreserveLogClicked, this);
  1654.  
  1655. this._clearButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear"), "clear-status-bar-item");
  1656. this._clearButton.addEventListener("click", this._reset, this);
  1657.  
  1658. this._largerRequestsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Use small resource rows."), "network-larger-resources-status-bar-item");
  1659. this._largerRequestsButton.toggled = WebInspector.settings.resourcesLargeRows.get();
  1660. this._largerRequestsButton.addEventListener("click", this._toggleLargerRequests, this);
  1661. },
  1662.  
  1663. _onLoadEventFired: function(event)
  1664. {
  1665. this._mainRequestLoadTime = event.data || -1;
  1666.  
  1667. this._scheduleRefresh();
  1668. },
  1669.  
  1670. _domContentLoadedEventFired: function(event)
  1671. {
  1672. this._mainRequestDOMContentTime = event.data || -1;
  1673.  
  1674. this._scheduleRefresh();
  1675. },
  1676.  
  1677. wasShown: function()
  1678. {
  1679. this._refreshIfNeeded();
  1680. },
  1681.  
  1682. willHide: function()
  1683. {
  1684. this._popoverHelper.hidePopover();
  1685. },
  1686.  
  1687. refresh: function()
  1688. {
  1689. this._needsRefresh = false;
  1690. if (this._refreshTimeout) {
  1691. clearTimeout(this._refreshTimeout);
  1692. delete this._refreshTimeout;
  1693. }
  1694.  
  1695. this._removeAllNodeHighlights();
  1696. var wasScrolledToLastRow = this._dataGrid.isScrolledToLastRow();
  1697. var boundariesChanged = false;
  1698. if (this.calculator.updateBoundariesForEventTime) {
  1699. boundariesChanged = this.calculator.updateBoundariesForEventTime(this._mainRequestLoadTime) || boundariesChanged;
  1700. boundariesChanged = this.calculator.updateBoundariesForEventTime(this._mainRequestDOMContentTime) || boundariesChanged;
  1701. }
  1702.  
  1703. for (var requestId in this._staleRequests) {
  1704. var request = this._staleRequests[requestId];
  1705. var node = this._requestGridNode(request);
  1706. if (!node) {
  1707.  
  1708. node = this._createRequestGridNode(request);
  1709. this._dataGrid.rootNode().appendChild(node);
  1710. }
  1711. node.refreshRequest();
  1712.  
  1713. if (this.calculator.updateBoundaries(request))
  1714. boundariesChanged = true;
  1715.  
  1716. if (!node.isFilteredOut())
  1717. this._updateHighlightIfMatched(request);
  1718. }
  1719.  
  1720. if (boundariesChanged) {
  1721.  
  1722. this._invalidateAllItems();
  1723. }
  1724.  
  1725. for (var requestId in this._staleRequests)
  1726. this._requestGridNode(this._staleRequests[requestId]).refreshGraph(this.calculator);
  1727.  
  1728. this._staleRequests = {};
  1729. this._sortItems();
  1730. this._updateSummaryBar();
  1731. this._dataGrid.updateWidths();
  1732.  
  1733. if (wasScrolledToLastRow)
  1734. this._dataGrid.scrollToLastRow();
  1735. },
  1736.  
  1737. _onPreserveLogClicked: function(e)
  1738. {
  1739. this._preserveLogToggle.toggled = !this._preserveLogToggle.toggled;
  1740. },
  1741.  
  1742. _reset: function()
  1743. {
  1744. this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.ViewCleared);
  1745.  
  1746. this._clearSearchMatchedList();
  1747. if (this._popoverHelper)
  1748. this._popoverHelper.hidePopover();
  1749.  
  1750. if (this._calculator)
  1751. this._calculator.reset();
  1752.  
  1753. this._requests = [];
  1754. this._requestsById = {};
  1755. this._requestsByURL = {};
  1756. this._staleRequests = {};
  1757. this._requestGridNodes = {};
  1758.  
  1759. if (this._dataGrid) {
  1760. this._dataGrid.rootNode().removeChildren();
  1761. this._updateDividersIfNeeded();
  1762. this._updateSummaryBar();
  1763. }
  1764.  
  1765. this._mainRequestLoadTime = -1;
  1766. this._mainRequestDOMContentTime = -1;
  1767. this._linkifier.reset();
  1768. },
  1769.  
  1770. get requests()
  1771. {
  1772. return this._requests;
  1773. },
  1774.  
  1775. requestById: function(id)
  1776. {
  1777. return this._requestsById[id];
  1778. },
  1779.  
  1780. _onRequestStarted: function(event)
  1781. {
  1782. this._appendRequest(event.data);
  1783. },
  1784.  
  1785. _appendRequest: function(request)
  1786. {
  1787. this._requests.push(request);
  1788.  
  1789.  
  1790.  
  1791. if (this._requestsById[request.requestId]) {
  1792. var oldRequest = request.redirects[request.redirects.length - 1];
  1793. this._requestsById[oldRequest.requestId] = oldRequest;
  1794.  
  1795. this._updateSearchMatchedListAfterRequestIdChanged(request.requestId, oldRequest.requestId);
  1796. }
  1797. this._requestsById[request.requestId] = request;
  1798.  
  1799. this._requestsByURL[request.url] = request;
  1800.  
  1801.  
  1802. if (request.redirects) {
  1803. for (var i = 0; i < request.redirects.length; ++i)
  1804. this._refreshRequest(request.redirects[i]);
  1805. }
  1806.  
  1807. this._refreshRequest(request);
  1808. },
  1809.  
  1810.  
  1811. _onRequestUpdated: function(event)
  1812. {
  1813. var request =   (event.data);
  1814. this._refreshRequest(request);
  1815. },
  1816.  
  1817.  
  1818. _refreshRequest: function(request)
  1819. {
  1820. this._staleRequests[request.requestId] = request;
  1821. this._scheduleRefresh();
  1822. },
  1823.  
  1824. clear: function()
  1825. {
  1826. if (this._preserveLogToggle.toggled)
  1827. return;
  1828. this._reset();
  1829. },
  1830.  
  1831. _mainFrameNavigated: function(event)
  1832. {
  1833. if (this._preserveLogToggle.toggled)
  1834. return;
  1835.  
  1836. var frame =   (event.data);
  1837. var loaderId = frame.loaderId;
  1838.  
  1839.  
  1840. var requestsToPreserve = [];
  1841. for (var i = 0; i < this._requests.length; ++i) {
  1842. var request = this._requests[i];
  1843. if (request.loaderId === loaderId)
  1844. requestsToPreserve.push(request);
  1845. }
  1846.  
  1847. this._reset();
  1848.  
  1849.  
  1850. for (var i = 0; i < requestsToPreserve.length; ++i)
  1851. this._appendRequest(requestsToPreserve[i]);
  1852. },
  1853.  
  1854. switchToDetailedView: function()
  1855. {
  1856. if (!this._dataGrid)
  1857. return;
  1858. if (this._dataGrid.selectedNode)
  1859. this._dataGrid.selectedNode.selected = false;
  1860.  
  1861. this.element.removeStyleClass("brief-mode");
  1862.  
  1863. this._dataGrid.showColumn("method");
  1864. this._dataGrid.showColumn("status");
  1865. this._dataGrid.showColumn("type");
  1866. this._dataGrid.showColumn("initiator");
  1867. this._dataGrid.showColumn("size");
  1868. this._dataGrid.showColumn("time");
  1869. this._dataGrid.showColumn("timeline");
  1870.  
  1871. var widths = {};
  1872. widths.name = 20;
  1873. widths.method = 6;
  1874. widths.status = 6;
  1875. widths.type = 6;
  1876. widths.initiator = 10;
  1877. widths.size = 6;
  1878. widths.time = 6;
  1879. widths.timeline = 40;
  1880.  
  1881. this._dataGrid.applyColumnWidthsMap(widths);
  1882. },
  1883.  
  1884. switchToBriefView: function()
  1885. {
  1886. this.element.addStyleClass("brief-mode");
  1887. this._removeAllNodeHighlights();
  1888.  
  1889. this._dataGrid.hideColumn("method");
  1890. this._dataGrid.hideColumn("status");
  1891. this._dataGrid.hideColumn("type");
  1892. this._dataGrid.hideColumn("initiator");
  1893. this._dataGrid.hideColumn("size");
  1894. this._dataGrid.hideColumn("time");
  1895. this._dataGrid.hideColumn("timeline");
  1896.  
  1897. var widths = {};
  1898. widths.name = 100;
  1899. this._dataGrid.applyColumnWidthsMap(widths);
  1900.  
  1901. this._popoverHelper.hidePopover();
  1902. },
  1903.  
  1904. _toggleLargerRequests: function()
  1905. {
  1906. WebInspector.settings.resourcesLargeRows.set(!WebInspector.settings.resourcesLargeRows.get());
  1907. this._setLargerRequests(WebInspector.settings.resourcesLargeRows.get());
  1908. },
  1909.  
  1910. _setLargerRequests: function(enabled)
  1911. {
  1912. this._largerRequestsButton.toggled = enabled;
  1913. if (!enabled) {
  1914. this._largerRequestsButton.title = WebInspector.UIString("Use large resource rows.");
  1915. this._dataGrid.element.addStyleClass("small");
  1916. this._timelineGrid.element.addStyleClass("small");
  1917. } else {
  1918. this._largerRequestsButton.title = WebInspector.UIString("Use small resource rows.");
  1919. this._dataGrid.element.removeStyleClass("small");
  1920. this._timelineGrid.element.removeStyleClass("small");
  1921. }
  1922. this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.RowSizeChanged, { largeRows: enabled });
  1923. this._updateOffscreenRows();
  1924. },
  1925.  
  1926. _getPopoverAnchor: function(element)
  1927. {
  1928. if (!this._allowPopover)
  1929. return;
  1930. var anchor = element.enclosingNodeOrSelfWithClass("network-graph-bar") || element.enclosingNodeOrSelfWithClass("network-graph-label");
  1931. if (!anchor)
  1932. return null;
  1933. var request = anchor.parentElement.request;
  1934. return request && request.timing ? anchor : null;
  1935. },
  1936.  
  1937.  
  1938. _showPopover: function(anchor, popover)
  1939. {
  1940. var request = anchor.parentElement.request;
  1941. var tableElement = WebInspector.RequestTimingView.createTimingTable(request);
  1942. popover.show(tableElement, anchor);
  1943. },
  1944.  
  1945. _contextMenu: function(event)
  1946. {
  1947. var contextMenu = new WebInspector.ContextMenu(event);
  1948. var gridNode = this._dataGrid.dataGridNodeFromNode(event.target);
  1949. var request = gridNode && gridNode._request;
  1950.  
  1951. if (request) {
  1952. contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, request.url, false));
  1953. contextMenu.appendSeparator();
  1954. contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), this._copyLocation.bind(this, request));
  1955. if (request.requestHeadersText)
  1956. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy request headers" : "Copy Request Headers"), this._copyRequestHeaders.bind(this, request));
  1957. if (request.responseHeadersText)
  1958. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy response headers" : "Copy Response Headers"), this._copyResponseHeaders.bind(this, request));
  1959. }
  1960. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy all as HAR" : "Copy All as HAR"), this._copyAll.bind(this));
  1961.  
  1962. if (InspectorFrontendHost.canSave()) {
  1963. contextMenu.appendSeparator();
  1964. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Save as HAR with content" : "Save as HAR with Content"), this._exportAll.bind(this));
  1965. }
  1966.  
  1967. if (this._canClearBrowserCache || this._canClearBrowserCookies)
  1968. contextMenu.appendSeparator();
  1969. if (this._canClearBrowserCache)
  1970. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear browser cache" : "Clear Browser Cache"), this._clearBrowserCache.bind(this));
  1971. if (this._canClearBrowserCookies)
  1972. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear browser cookies" : "Clear Browser Cookies"), this._clearBrowserCookies.bind(this));
  1973.  
  1974.  
  1975. if (request && request.type === WebInspector.resourceTypes.XHR) {
  1976. contextMenu.appendSeparator();
  1977. contextMenu.appendItem(WebInspector.UIString("Replay XHR"), this._replayXHR.bind(this, request.requestId));
  1978. contextMenu.appendSeparator();
  1979. }
  1980.  
  1981. contextMenu.show();
  1982. },
  1983.  
  1984. _replayXHR: function(requestId)
  1985. {
  1986. NetworkAgent.replayXHR(requestId);
  1987. },
  1988.  
  1989.  
  1990. _copyAll: function()
  1991. {
  1992. var harArchive = {
  1993. log: (new WebInspector.HARLog(this._requests)).build()
  1994. };
  1995. InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2));
  1996. },
  1997.  
  1998. _copyLocation: function(request)
  1999. {
  2000. InspectorFrontendHost.copyText(request.url);
  2001. },
  2002.  
  2003. _copyRequestHeaders: function(request)
  2004. {
  2005. InspectorFrontendHost.copyText(request.requestHeadersText);
  2006. },
  2007.  
  2008. _copyResponseHeaders: function(request)
  2009. {
  2010. InspectorFrontendHost.copyText(request.responseHeadersText);
  2011. },
  2012.  
  2013. _exportAll: function()
  2014. {
  2015. var filename = WebInspector.inspectedPageDomain + ".har";
  2016. var stream = new WebInspector.FileOutputStream();
  2017. stream.open(filename, openCallback.bind(this));
  2018. function openCallback()
  2019. {
  2020. var progressIndicator = new WebInspector.ProgressIndicator();
  2021. this._progressBarContainer.appendChild(progressIndicator.element);
  2022. var harWriter = new WebInspector.HARWriter();
  2023. harWriter.write(stream, this._requests, progressIndicator);
  2024. }
  2025. },
  2026.  
  2027. _clearBrowserCache: function(event)
  2028. {
  2029. if (confirm(WebInspector.UIString("Are you sure you want to clear browser cache?")))
  2030. NetworkAgent.clearBrowserCache();
  2031. },
  2032.  
  2033. _clearBrowserCookies: function(event)
  2034. {
  2035. if (confirm(WebInspector.UIString("Are you sure you want to clear browser cookies?")))
  2036. NetworkAgent.clearBrowserCookies();
  2037. },
  2038.  
  2039. _updateOffscreenRows: function()
  2040. {
  2041. var dataTableBody = this._dataGrid.dataTableBody;
  2042. var rows = dataTableBody.children;
  2043. var recordsCount = rows.length;
  2044. if (recordsCount < 2)
  2045. return;  
  2046.  
  2047. var visibleTop = this._dataGrid.scrollContainer.scrollTop;
  2048. var visibleBottom = visibleTop + this._dataGrid.scrollContainer.offsetHeight;
  2049.  
  2050. var rowHeight = 0;
  2051.  
  2052.  
  2053. var unfilteredRowIndex = 0;
  2054. for (var i = 0; i < recordsCount - 1; ++i) {
  2055. var row = rows[i];
  2056.  
  2057. var dataGridNode = this._dataGrid.dataGridNodeFromNode(row);
  2058. if (dataGridNode.isFilteredOut()) {
  2059. row.removeStyleClass("offscreen");
  2060. continue;
  2061. }
  2062.  
  2063. if (!rowHeight)
  2064. rowHeight = row.offsetHeight;
  2065.  
  2066. var rowIsVisible = unfilteredRowIndex * rowHeight < visibleBottom && (unfilteredRowIndex + 1) * rowHeight > visibleTop;
  2067. if (rowIsVisible !== row.rowIsVisible) {
  2068. if (rowIsVisible)
  2069. row.removeStyleClass("offscreen");
  2070. else
  2071. row.addStyleClass("offscreen");
  2072. row.rowIsVisible = rowIsVisible;
  2073. }
  2074. unfilteredRowIndex++;
  2075. }
  2076. },
  2077.  
  2078. _matchRequest: function(request)
  2079. {
  2080. if (!this._searchRegExp)
  2081. return -1;
  2082.  
  2083. if (!request.name().match(this._searchRegExp) && !request.path().match(this._searchRegExp))
  2084. return -1;
  2085.  
  2086. if (request.requestId in this._matchedRequestsMap)
  2087. return this._matchedRequestsMap[request.requestId];
  2088.  
  2089. var matchedRequestIndex = this._matchedRequests.length;
  2090. this._matchedRequestsMap[request.requestId] = matchedRequestIndex;
  2091. this._matchedRequests.push(request.requestId);
  2092.  
  2093. return matchedRequestIndex;
  2094. },
  2095.  
  2096. _clearSearchMatchedList: function()
  2097. {
  2098. delete this._searchRegExp;
  2099. this._matchedRequests = [];
  2100. this._matchedRequestsMap = {};
  2101. this._removeAllHighlights();
  2102. },
  2103.  
  2104. _updateSearchMatchedListAfterRequestIdChanged: function(oldRequestId, newRequestId)
  2105. {
  2106. var requestIndex = this._matchedRequestsMap[oldRequestId];
  2107. if (requestIndex) {
  2108. delete this._matchedRequestsMap[oldRequestId];
  2109. this._matchedRequestsMap[newRequestId] = requestIndex;
  2110. this._matchedRequests[requestIndex] = newRequestId;
  2111. }
  2112. },
  2113.  
  2114. _updateHighlightIfMatched: function(request)
  2115. {
  2116. var matchedRequestIndex = this._matchRequest(request);
  2117. if (matchedRequestIndex === -1)
  2118. return;
  2119.  
  2120. this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated, this._matchedRequests.length);
  2121.  
  2122. if (this._currentMatchedRequestIndex !== -1 && this._currentMatchedRequestIndex !== matchedRequestIndex)
  2123. return;
  2124.  
  2125. this._highlightNthMatchedRequestForSearch(matchedRequestIndex, false);
  2126. },
  2127.  
  2128. _removeAllHighlights: function()
  2129. {
  2130. if (this._highlightedSubstringChanges) {
  2131. for (var i = 0; i < this._highlightedSubstringChanges.length; ++i)
  2132. WebInspector.revertDomChanges(this._highlightedSubstringChanges[i]);
  2133. this._highlightedSubstringChanges = null;
  2134. }
  2135. },
  2136.  
  2137.  
  2138. _highlightMatchedRequests: function(requests, reveal, regExp)
  2139. {
  2140. this._highlightedSubstringChanges = [];
  2141. for (var i = 0; i < requests.length; ++i) {
  2142. var request = requests[i];
  2143. var node = this._requestGridNode(request);
  2144. if (node) {
  2145. var nameMatched = request.name().match(regExp);
  2146. var pathMatched = request.path().match(regExp);
  2147. if (!nameMatched && pathMatched && !this._largerRequestsButton.toggled)
  2148. this._toggleLargerRequests();
  2149. var highlightedSubstringChanges = node._highlightMatchedSubstring(regExp);
  2150. this._highlightedSubstringChanges.push(highlightedSubstringChanges);
  2151. if (reveal)
  2152. node.reveal();
  2153. }
  2154. }
  2155. },
  2156.  
  2157.  
  2158. _highlightNthMatchedRequestForSearch: function(matchedRequestIndex, reveal)
  2159. {
  2160. var request = this.requestById(this._matchedRequests[matchedRequestIndex]);
  2161. if (!request)
  2162. return;
  2163. this._removeAllHighlights();
  2164. this._highlightMatchedRequests([request], reveal, this._searchRegExp);
  2165. var node = this._requestGridNode(request);
  2166. if (node)
  2167. this._currentMatchedRequestIndex = matchedRequestIndex;
  2168.  
  2169. this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchIndexUpdated, this._currentMatchedRequestIndex);
  2170. },
  2171.  
  2172. performSearch: function(searchQuery)
  2173. {
  2174. var newMatchedRequestIndex = 0;
  2175. var currentMatchedRequestId;
  2176. if (this._currentMatchedRequestIndex !== -1)
  2177. currentMatchedRequestId = this._matchedRequests[this._currentMatchedRequestIndex];
  2178.  
  2179. this._clearSearchMatchedList();
  2180. this._searchRegExp = createPlainTextSearchRegex(searchQuery, "i");
  2181.  
  2182. var childNodes = this._dataGrid.dataTableBody.childNodes;
  2183. var requestNodes = Array.prototype.slice.call(childNodes, 0, childNodes.length - 1); 
  2184.  
  2185. for (var i = 0; i < requestNodes.length; ++i) {
  2186. var dataGridNode = this._dataGrid.dataGridNodeFromNode(requestNodes[i]);
  2187. if (dataGridNode.isFilteredOut())
  2188. continue;
  2189. if (this._matchRequest(dataGridNode._request) !== -1 && dataGridNode._request.requestId === currentMatchedRequestId)
  2190. newMatchedRequestIndex = this._matchedRequests.length - 1;
  2191. }
  2192.  
  2193. this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated, this._matchedRequests.length);
  2194. this._highlightNthMatchedRequestForSearch(newMatchedRequestIndex, false);
  2195. },
  2196.  
  2197.  
  2198. performFilter: function(query)
  2199. {
  2200. this._filteredOutRequests.clear();
  2201. var filterRegExp = createPlainTextSearchRegex(query, "i");
  2202. var shownRequests = [];
  2203. for (var i = 0; i < this._dataGrid.rootNode().children.length; ++i) {
  2204. var node = this._dataGrid.rootNode().children[i];
  2205. node.element.removeStyleClass("filtered-out");
  2206. var nameMatched = node._request.name().match(filterRegExp);
  2207. var pathMatched = node._request.path().match(filterRegExp);
  2208. if (!nameMatched && !pathMatched) {
  2209. node.element.addStyleClass("filtered-out");
  2210. this._filteredOutRequests.put(this._requests[i], true);
  2211. } else 
  2212. shownRequests.push(node._request);
  2213. }
  2214. this._removeAllHighlights();
  2215. if (query)
  2216. this._highlightMatchedRequests(shownRequests, false, filterRegExp);
  2217. this._updateSummaryBar();
  2218. this._updateOffscreenRows();
  2219. },
  2220.  
  2221. jumpToPreviousSearchResult: function()
  2222. {
  2223. if (!this._matchedRequests.length)
  2224. return;
  2225. this._highlightNthMatchedRequestForSearch((this._currentMatchedRequestIndex + this._matchedRequests.length - 1) % this._matchedRequests.length, true);
  2226. },
  2227.  
  2228. jumpToNextSearchResult: function()
  2229. {
  2230. if (!this._matchedRequests.length)
  2231. return;
  2232. this._highlightNthMatchedRequestForSearch((this._currentMatchedRequestIndex + 1) % this._matchedRequests.length, true);
  2233. },
  2234.  
  2235. searchCanceled: function()
  2236. {
  2237. this._clearSearchMatchedList();
  2238. this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated, 0);
  2239. },
  2240.  
  2241. revealAndHighlightRequest: function(request)
  2242. {
  2243. this._removeAllNodeHighlights();
  2244.  
  2245. var node = this._requestGridNode(request);
  2246. if (node) {
  2247. this._dataGrid.element.focus();
  2248. node.reveal();
  2249. this._highlightNode(node);
  2250. }
  2251. },
  2252.  
  2253. _removeAllNodeHighlights: function()
  2254. {
  2255. if (this._highlightedNode) {
  2256. this._highlightedNode.element.removeStyleClass("highlighted-row");
  2257. delete this._highlightedNode;
  2258. }
  2259. },
  2260.  
  2261. _highlightNode: function(node)
  2262. {
  2263. node.element.addStyleClass("highlighted-row");
  2264. this._highlightedNode = node;
  2265. },
  2266.  
  2267. __proto__: WebInspector.View.prototype
  2268. }
  2269.  
  2270.  
  2271. WebInspector.NetworkLogView.EventTypes = {
  2272. ViewCleared: "ViewCleared",
  2273. RowSizeChanged: "RowSizeChanged",
  2274. RequestSelected: "RequestSelected",
  2275. SearchCountUpdated: "SearchCountUpdated",
  2276. SearchIndexUpdated: "SearchIndexUpdated"
  2277. };
  2278.  
  2279.  
  2280. WebInspector.NetworkPanel = function()
  2281. {
  2282. WebInspector.Panel.call(this, "network");
  2283. this.registerRequiredCSS("networkPanel.css");
  2284.  
  2285. this.createSidebarView();
  2286. this.splitView.hideMainElement();
  2287.  
  2288. this._networkLogView = new WebInspector.NetworkLogView();
  2289. this._networkLogView.show(this.sidebarElement);
  2290.  
  2291. this._viewsContainerElement = this.splitView.mainElement;
  2292. this._viewsContainerElement.id = "network-views";
  2293. this._viewsContainerElement.addStyleClass("hidden");
  2294. if (!this._networkLogView.useLargeRows)
  2295. this._viewsContainerElement.addStyleClass("small");
  2296.  
  2297. this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.ViewCleared, this._onViewCleared, this);
  2298. this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.RowSizeChanged, this._onRowSizeChanged, this);
  2299. this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.RequestSelected, this._onRequestSelected, this);
  2300. this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated, this._onSearchCountUpdated, this);
  2301. this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.SearchIndexUpdated, this._onSearchIndexUpdated, this);
  2302.  
  2303. this._closeButtonElement = document.createElement("button");
  2304. this._closeButtonElement.id = "network-close-button";
  2305. this._closeButtonElement.addEventListener("click", this._toggleGridMode.bind(this), false);
  2306. this._viewsContainerElement.appendChild(this._closeButtonElement);
  2307.  
  2308. function viewGetter()
  2309. {
  2310. return this.visibleView;
  2311. }
  2312. WebInspector.GoToLineDialog.install(this, viewGetter.bind(this));
  2313. }
  2314.  
  2315. WebInspector.NetworkPanel.prototype = {
  2316. get statusBarItems()
  2317. {
  2318. return this._networkLogView.statusBarItems;
  2319. },
  2320.  
  2321. elementsToRestoreScrollPositionsFor: function()
  2322. {
  2323. return this._networkLogView.elementsToRestoreScrollPositionsFor();
  2324. },
  2325.  
  2326.  
  2327. _reset: function()
  2328. {
  2329. this._networkLogView._reset();
  2330. },
  2331.  
  2332. handleShortcut: function(event)
  2333. {
  2334. if (this._viewingRequestMode && event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
  2335. this._toggleGridMode();
  2336. event.handled = true;
  2337. return;
  2338. }
  2339.  
  2340. WebInspector.Panel.prototype.handleShortcut.call(this, event);
  2341. },
  2342.  
  2343. wasShown: function()
  2344. {
  2345. WebInspector.Panel.prototype.wasShown.call(this);
  2346. },
  2347.  
  2348. get requests()
  2349. {
  2350. return this._networkLogView.requests;
  2351. },
  2352.  
  2353. requestById: function(id)
  2354. {
  2355. return this._networkLogView.requestById(id);
  2356. },
  2357.  
  2358. _requestByAnchor: function(anchor)
  2359. {
  2360. return anchor.requestId ? this.requestById(anchor.requestId) : this._networkLogView._requestsByURL[anchor.href];
  2361. },
  2362.  
  2363. canShowAnchorLocation: function(anchor)
  2364. {
  2365. return !!this._requestByAnchor(anchor);
  2366. },
  2367.  
  2368. showAnchorLocation: function(anchor)
  2369. {
  2370. var request = this._requestByAnchor(anchor);
  2371. this.revealAndHighlightRequest(request)
  2372. },
  2373.  
  2374. revealAndHighlightRequest: function(request)
  2375. {
  2376. this._toggleGridMode();
  2377. if (request)
  2378. this._networkLogView.revealAndHighlightRequest(request);
  2379. },
  2380.  
  2381. _onViewCleared: function(event)
  2382. {
  2383. this._closeVisibleRequest();
  2384. this._toggleGridMode();
  2385. this._viewsContainerElement.removeChildren();
  2386. this._viewsContainerElement.appendChild(this._closeButtonElement);
  2387. },
  2388.  
  2389. _onRowSizeChanged: function(event)
  2390. {
  2391. if (event.data.largeRows)
  2392. this._viewsContainerElement.removeStyleClass("small");
  2393. else
  2394. this._viewsContainerElement.addStyleClass("small");
  2395. },
  2396.  
  2397. _onSearchCountUpdated: function(event)
  2398. {
  2399. WebInspector.searchController.updateSearchMatchesCount(event.data, this);
  2400. },
  2401.  
  2402. _onSearchIndexUpdated: function(event)
  2403. {
  2404. WebInspector.searchController.updateCurrentMatchIndex(event.data, this);
  2405. },
  2406.  
  2407. _onRequestSelected: function(event)
  2408. {
  2409. this._showRequest(event.data);
  2410. },
  2411.  
  2412. _showRequest: function(request)
  2413. {
  2414. if (!request)
  2415. return;
  2416.  
  2417. this._toggleViewingRequestMode();
  2418.  
  2419. if (this.visibleView) {
  2420. this.visibleView.detach();
  2421. delete this.visibleView;
  2422. }
  2423.  
  2424. var view = new WebInspector.NetworkItemView(request);
  2425. view.show(this._viewsContainerElement);
  2426. this.visibleView = view;
  2427. },
  2428.  
  2429. _closeVisibleRequest: function()
  2430. {
  2431. this.element.removeStyleClass("viewing-resource");
  2432.  
  2433. if (this.visibleView) {
  2434. this.visibleView.detach();
  2435. delete this.visibleView;
  2436. }
  2437. },
  2438.  
  2439. _toggleGridMode: function()
  2440. {
  2441. if (this._viewingRequestMode) {
  2442. this._viewingRequestMode = false;
  2443. this.element.removeStyleClass("viewing-resource");
  2444. this.splitView.hideMainElement();
  2445. }
  2446.  
  2447. this._networkLogView.switchToDetailedView();
  2448. this._networkLogView.allowPopover = true;
  2449. this._networkLogView._allowRequestSelection = false;
  2450. },
  2451.  
  2452. _toggleViewingRequestMode: function()
  2453. {
  2454. if (this._viewingRequestMode)
  2455. return;
  2456. this._viewingRequestMode = true;
  2457.  
  2458. this.element.addStyleClass("viewing-resource");
  2459. this.splitView.showMainElement();
  2460. this._networkLogView.allowPopover = false;
  2461. this._networkLogView._allowRequestSelection = true;
  2462. this._networkLogView.switchToBriefView();
  2463. },
  2464.  
  2465.  
  2466. performSearch: function(searchQuery)
  2467. {
  2468. this._networkLogView.performSearch(searchQuery);
  2469. },
  2470.  
  2471.  
  2472. canFilter: function()
  2473. {
  2474. return true;
  2475. },
  2476.  
  2477.  
  2478. performFilter: function(query)
  2479. {
  2480. this._networkLogView.performFilter(query);
  2481. },
  2482.  
  2483. jumpToPreviousSearchResult: function()
  2484. {
  2485. this._networkLogView.jumpToPreviousSearchResult();
  2486. },
  2487.  
  2488. jumpToNextSearchResult: function()
  2489. {
  2490. this._networkLogView.jumpToNextSearchResult();
  2491. },
  2492.  
  2493. searchCanceled: function()
  2494. {
  2495. this._networkLogView.searchCanceled();
  2496. },
  2497.  
  2498.  
  2499. appendApplicableItems: function(event, contextMenu, target)
  2500. {
  2501. if (!(target instanceof WebInspector.NetworkRequest))
  2502. return;
  2503. if (this.visibleView && this.visibleView.isShowing() && this.visibleView.request() === target)
  2504. return;
  2505.  
  2506. function reveal()
  2507. {
  2508. WebInspector.inspectorView.setCurrentPanel(this);
  2509. this.revealAndHighlightRequest(  (target));
  2510. }
  2511. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in network panel" : "Reveal in Network Panel"), reveal.bind(this));
  2512. },
  2513.  
  2514. __proto__: WebInspector.Panel.prototype
  2515. }
  2516.  
  2517.  
  2518. WebInspector.NetworkBaseCalculator = function()
  2519. {
  2520. }
  2521.  
  2522. WebInspector.NetworkBaseCalculator.prototype = {
  2523. computePosition: function(time)
  2524. {
  2525. return (time - this._minimumBoundary) / this.boundarySpan() * this._workingArea;
  2526. },
  2527.  
  2528. computeBarGraphPercentages: function(item)
  2529. {
  2530. return {start: 0, middle: 0, end: (this._value(item) / this.boundarySpan()) * 100};
  2531. },
  2532.  
  2533. computeBarGraphLabels: function(item)
  2534. {
  2535. const label = this.formatTime(this._value(item));
  2536. return {left: label, right: label, tooltip: label};
  2537. },
  2538.  
  2539. boundarySpan: function()
  2540. {
  2541. return this._maximumBoundary - this._minimumBoundary;
  2542. },
  2543.  
  2544. updateBoundaries: function(item)
  2545. {
  2546. this._minimumBoundary = 0;
  2547.  
  2548. var value = this._value(item);
  2549. if (typeof this._maximumBoundary === "undefined" || value > this._maximumBoundary) {
  2550. this._maximumBoundary = value;
  2551. return true;
  2552. }
  2553. return false;
  2554. },
  2555.  
  2556. reset: function()
  2557. {
  2558. delete this._minimumBoundary;
  2559. delete this._maximumBoundary;
  2560. },
  2561.  
  2562. maximumBoundary: function()
  2563. {
  2564. return this._maximumBoundary;
  2565. },
  2566.  
  2567. minimumBoundary: function()
  2568. {
  2569. return this._minimumBoundary;
  2570. },
  2571.  
  2572. _value: function(item)
  2573. {
  2574. return 0;
  2575. },
  2576.  
  2577. formatTime: function(value)
  2578. {
  2579. return value.toString();
  2580. },
  2581.  
  2582. setDisplayWindow: function(clientWidth)
  2583. {
  2584. this._workingArea = clientWidth;
  2585. this.paddingLeft = 0;
  2586. }
  2587. }
  2588.  
  2589.  
  2590. WebInspector.NetworkTimeCalculator = function(startAtZero)
  2591. {
  2592. WebInspector.NetworkBaseCalculator.call(this);
  2593. this.startAtZero = startAtZero;
  2594. }
  2595.  
  2596. WebInspector.NetworkTimeCalculator.prototype = {
  2597. computeBarGraphPercentages: function(request)
  2598. {
  2599. if (request.startTime !== -1)
  2600. var start = ((request.startTime - this._minimumBoundary) / this.boundarySpan()) * 100;
  2601. else
  2602. var start = 0;
  2603.  
  2604. if (request.responseReceivedTime !== -1)
  2605. var middle = ((request.responseReceivedTime - this._minimumBoundary) / this.boundarySpan()) * 100;
  2606. else
  2607. var middle = (this.startAtZero ? start : 100);
  2608.  
  2609. if (request.endTime !== -1)
  2610. var end = ((request.endTime - this._minimumBoundary) / this.boundarySpan()) * 100;
  2611. else
  2612. var end = (this.startAtZero ? middle : 100);
  2613.  
  2614. if (this.startAtZero) {
  2615. end -= start;
  2616. middle -= start;
  2617. start = 0;
  2618. }
  2619.  
  2620. return {start: start, middle: middle, end: end};
  2621. },
  2622.  
  2623. computePercentageFromEventTime: function(eventTime)
  2624. {
  2625.  
  2626.  
  2627.  
  2628. if (eventTime !== -1 && !this.startAtZero)
  2629. return ((eventTime - this._minimumBoundary) / this.boundarySpan()) * 100;
  2630.  
  2631. return 0;
  2632. },
  2633.  
  2634. updateBoundariesForEventTime: function(eventTime)
  2635. {
  2636. if (eventTime === -1 || this.startAtZero)
  2637. return false;
  2638.  
  2639. if (typeof this._maximumBoundary === "undefined" || eventTime > this._maximumBoundary) {
  2640. this._maximumBoundary = eventTime;
  2641. return true;
  2642. }
  2643. return false;
  2644. },
  2645.  
  2646. computeBarGraphLabels: function(request)
  2647. {
  2648. var rightLabel = "";
  2649. if (request.responseReceivedTime !== -1 && request.endTime !== -1)
  2650. rightLabel = this.formatTime(request.endTime - request.responseReceivedTime);
  2651.  
  2652. var hasLatency = request.latency > 0;
  2653. if (hasLatency)
  2654. var leftLabel = this.formatTime(request.latency);
  2655. else
  2656. var leftLabel = rightLabel;
  2657.  
  2658. if (request.timing)
  2659. return {left: leftLabel, right: rightLabel};
  2660.  
  2661. if (hasLatency && rightLabel) {
  2662. var total = this.formatTime(request.duration);
  2663. var tooltip = WebInspector.UIString("%s latency, %s download (%s total)", leftLabel, rightLabel, total);
  2664. } else if (hasLatency)
  2665. var tooltip = WebInspector.UIString("%s latency", leftLabel);
  2666. else if (rightLabel)
  2667. var tooltip = WebInspector.UIString("%s download", rightLabel);
  2668.  
  2669. if (request.cached)
  2670. tooltip = WebInspector.UIString("%s (from cache)", tooltip);
  2671. return {left: leftLabel, right: rightLabel, tooltip: tooltip};
  2672. },
  2673.  
  2674. updateBoundaries: function(request)
  2675. {
  2676. var didChange = false;
  2677.  
  2678. var lowerBound;
  2679. if (this.startAtZero)
  2680. lowerBound = 0;
  2681. else
  2682. lowerBound = this._lowerBound(request);
  2683.  
  2684. if (lowerBound !== -1 && (typeof this._minimumBoundary === "undefined" || lowerBound < this._minimumBoundary)) {
  2685. this._minimumBoundary = lowerBound;
  2686. didChange = true;
  2687. }
  2688.  
  2689. var upperBound = this._upperBound(request);
  2690. if (upperBound !== -1 && (typeof this._maximumBoundary === "undefined" || upperBound > this._maximumBoundary)) {
  2691. this._maximumBoundary = upperBound;
  2692. didChange = true;
  2693. }
  2694.  
  2695. return didChange;
  2696. },
  2697.  
  2698. formatTime: function(value)
  2699. {
  2700. return Number.secondsToString(value);
  2701. },
  2702.  
  2703. _lowerBound: function(request)
  2704. {
  2705. return 0;
  2706. },
  2707.  
  2708. _upperBound: function(request)
  2709. {
  2710. return 0;
  2711. },
  2712.  
  2713. __proto__: WebInspector.NetworkBaseCalculator.prototype
  2714. }
  2715.  
  2716.  
  2717. WebInspector.NetworkTransferTimeCalculator = function()
  2718. {
  2719. WebInspector.NetworkTimeCalculator.call(this, false);
  2720. }
  2721.  
  2722. WebInspector.NetworkTransferTimeCalculator.prototype = {
  2723. formatTime: function(value)
  2724. {
  2725. return Number.secondsToString(value);
  2726. },
  2727.  
  2728. _lowerBound: function(request)
  2729. {
  2730. return request.startTime;
  2731. },
  2732.  
  2733. _upperBound: function(request)
  2734. {
  2735. return request.endTime;
  2736. },
  2737.  
  2738. __proto__: WebInspector.NetworkTimeCalculator.prototype
  2739. }
  2740.  
  2741.  
  2742. WebInspector.NetworkTransferDurationCalculator = function()
  2743. {
  2744. WebInspector.NetworkTimeCalculator.call(this, true);
  2745. }
  2746.  
  2747. WebInspector.NetworkTransferDurationCalculator.prototype = {
  2748. formatTime: function(value)
  2749. {
  2750. return Number.secondsToString(value);
  2751. },
  2752.  
  2753. _upperBound: function(request)
  2754. {
  2755. return request.duration;
  2756. },
  2757.  
  2758. __proto__: WebInspector.NetworkTimeCalculator.prototype
  2759. }
  2760.  
  2761.  
  2762. WebInspector.NetworkDataGridNode = function(parentView, request)
  2763. {
  2764. WebInspector.DataGridNode.call(this, {});
  2765. this._parentView = parentView;
  2766. this._request = request;
  2767. }
  2768.  
  2769. WebInspector.NetworkDataGridNode.prototype = {
  2770. createCells: function()
  2771. {
  2772.  
  2773. this._element.addStyleClass("offscreen");
  2774. this._nameCell = this._createDivInTD("name");
  2775. this._methodCell = this._createDivInTD("method");
  2776. this._statusCell = this._createDivInTD("status");
  2777. this._typeCell = this._createDivInTD("type");
  2778. this._initiatorCell = this._createDivInTD("initiator");
  2779. this._sizeCell = this._createDivInTD("size");
  2780. this._timeCell = this._createDivInTD("time");
  2781. this._createTimelineCell();
  2782. this._nameCell.addEventListener("click", this.select.bind(this), false);
  2783. this._nameCell.addEventListener("dblclick", this._openInNewTab.bind(this), false);
  2784. },
  2785.  
  2786. isFilteredOut: function()
  2787. {
  2788. if (this._parentView._filteredOutRequests.get(this._request))
  2789. return true;
  2790. if (!this._parentView._hiddenCategories.all)
  2791. return false;
  2792. return this._request.type.name() in this._parentView._hiddenCategories;
  2793. },
  2794.  
  2795. select: function()
  2796. {
  2797. this._parentView.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.RequestSelected, this._request);
  2798. WebInspector.DataGridNode.prototype.select.apply(this, arguments);
  2799. },
  2800.  
  2801. _highlightMatchedSubstring: function(regexp)
  2802. {
  2803. var domChanges = [];
  2804. var matchInfo = this._element.textContent.match(regexp);
  2805. if (matchInfo)
  2806. WebInspector.highlightSearchResult(this._nameCell, matchInfo.index, matchInfo[0].length, domChanges);
  2807. return domChanges;
  2808. },
  2809.  
  2810. _openInNewTab: function()
  2811. {
  2812. InspectorFrontendHost.openInNewTab(this._request.url);
  2813. },
  2814.  
  2815. get selectable()
  2816. {
  2817. return this._parentView._allowRequestSelection && !this.isFilteredOut();
  2818. },
  2819.  
  2820. _createDivInTD: function(columnIdentifier)
  2821. {
  2822. var td = document.createElement("td");
  2823. td.className = columnIdentifier + "-column";
  2824. var div = document.createElement("div");
  2825. td.appendChild(div);
  2826. this._element.appendChild(td);
  2827. return div;
  2828. },
  2829.  
  2830. _createTimelineCell: function()
  2831. {
  2832. this._graphElement = document.createElement("div");
  2833. this._graphElement.className = "network-graph-side";
  2834.  
  2835. this._barAreaElement = document.createElement("div");
  2836.  
  2837. this._barAreaElement.className = "network-graph-bar-area";
  2838. this._barAreaElement.request = this._request;
  2839. this._graphElement.appendChild(this._barAreaElement);
  2840.  
  2841. this._barLeftElement = document.createElement("div");
  2842. this._barLeftElement.className = "network-graph-bar waiting";
  2843. this._barAreaElement.appendChild(this._barLeftElement);
  2844.  
  2845. this._barRightElement = document.createElement("div");
  2846. this._barRightElement.className = "network-graph-bar";
  2847. this._barAreaElement.appendChild(this._barRightElement);
  2848.  
  2849.  
  2850. this._labelLeftElement = document.createElement("div");
  2851. this._labelLeftElement.className = "network-graph-label waiting";
  2852. this._barAreaElement.appendChild(this._labelLeftElement);
  2853.  
  2854. this._labelRightElement = document.createElement("div");
  2855. this._labelRightElement.className = "network-graph-label";
  2856. this._barAreaElement.appendChild(this._labelRightElement);
  2857.  
  2858. this._graphElement.addEventListener("mouseover", this._refreshLabelPositions.bind(this), false);
  2859.  
  2860. this._timelineCell = document.createElement("td");
  2861. this._timelineCell.className = "timeline-column";
  2862. this._element.appendChild(this._timelineCell);
  2863. this._timelineCell.appendChild(this._graphElement);
  2864. },
  2865.  
  2866. refreshRequest: function()
  2867. {
  2868. this._refreshNameCell();
  2869.  
  2870. this._methodCell.setTextAndTitle(this._request.requestMethod);
  2871.  
  2872. this._refreshStatusCell();
  2873. this._refreshTypeCell();
  2874. this._refreshInitiatorCell();
  2875. this._refreshSizeCell();
  2876. this._refreshTimeCell();
  2877.  
  2878. if (this._request.cached)
  2879. this._graphElement.addStyleClass("resource-cached");
  2880.  
  2881. this._element.addStyleClass("network-item");
  2882. if (!this._element.hasStyleClass("network-type-" + this._request.type.name())) {
  2883. this._element.removeMatchingStyleClasses("network-type-\\w+");
  2884. this._element.addStyleClass("network-type-" + this._request.type.name());
  2885. }
  2886. },
  2887.  
  2888. _refreshNameCell: function()
  2889. {
  2890. this._nameCell.removeChildren();
  2891.  
  2892. if (this._request.type === WebInspector.resourceTypes.Image) {
  2893. var previewImage = document.createElement("img");
  2894. previewImage.className = "image-network-icon-preview";
  2895. this._request.populateImageSource(previewImage);
  2896.  
  2897. var iconElement = document.createElement("div");
  2898. iconElement.className = "icon";
  2899. iconElement.appendChild(previewImage);
  2900. } else {
  2901. var iconElement = document.createElement("img");
  2902. iconElement.className = "icon";
  2903. }
  2904. this._nameCell.appendChild(iconElement);
  2905. this._nameCell.appendChild(document.createTextNode(this._request.name()));
  2906. this._appendSubtitle(this._nameCell, this._request.path());
  2907. this._nameCell.title = this._request.url;
  2908. },
  2909.  
  2910. _refreshStatusCell: function()
  2911. {
  2912. this._statusCell.removeChildren();
  2913.  
  2914. if (this._request.failed) {
  2915. var failText = this._request.canceled ? WebInspector.UIString("(canceled)") : WebInspector.UIString("(failed)");
  2916. if (this._request.localizedFailDescription) {
  2917. this._statusCell.appendChild(document.createTextNode(failText));
  2918. this._appendSubtitle(this._statusCell, this._request.localizedFailDescription);
  2919. this._statusCell.title = failText + " " + this._request.localizedFailDescription;
  2920. } else {
  2921. this._statusCell.setTextAndTitle(failText);
  2922. }
  2923. this._statusCell.addStyleClass("network-dim-cell");
  2924. this.element.addStyleClass("network-error-row");
  2925. return;
  2926. }
  2927.  
  2928. this._statusCell.removeStyleClass("network-dim-cell");
  2929. this.element.removeStyleClass("network-error-row");
  2930.  
  2931. if (this._request.statusCode) {
  2932. this._statusCell.appendChild(document.createTextNode(this._request.statusCode));
  2933. this._appendSubtitle(this._statusCell, this._request.statusText);
  2934. this._statusCell.title = this._request.statusCode + " " + this._request.statusText;
  2935. if (this._request.statusCode >= 400)
  2936. this.element.addStyleClass("network-error-row");
  2937. if (this._request.cached)
  2938. this._statusCell.addStyleClass("network-dim-cell");
  2939. } else {
  2940. if (!this._request.isHttpFamily() && this._request.finished)
  2941. this._statusCell.setTextAndTitle(WebInspector.UIString("Success"));
  2942. else if (this._request.isPingRequest())
  2943. this._statusCell.setTextAndTitle(WebInspector.UIString("(ping)"));
  2944. else
  2945. this._statusCell.setTextAndTitle(WebInspector.UIString("(pending)"));
  2946. this._statusCell.addStyleClass("network-dim-cell");
  2947. }
  2948. },
  2949.  
  2950. _refreshTypeCell: function()
  2951. {
  2952. if (this._request.mimeType) {
  2953. this._typeCell.removeStyleClass("network-dim-cell");
  2954. this._typeCell.setTextAndTitle(this._request.mimeType);
  2955. } else if (this._request.isPingRequest()) {
  2956. this._typeCell.removeStyleClass("network-dim-cell");
  2957. this._typeCell.setTextAndTitle(this._request.requestContentType());
  2958. } else {
  2959. this._typeCell.addStyleClass("network-dim-cell");
  2960. this._typeCell.setTextAndTitle(WebInspector.UIString("Pending"));
  2961. }
  2962. },
  2963.  
  2964. _refreshInitiatorCell: function()
  2965. {
  2966. var initiator = this._request.initiator;
  2967. if ((initiator && initiator.type !== "other") || this._request.redirectSource) {
  2968. this._initiatorCell.removeStyleClass("network-dim-cell");
  2969. this._initiatorCell.removeChildren();
  2970. if (this._request.redirectSource) {
  2971. var redirectSource = this._request.redirectSource;
  2972. this._initiatorCell.title = redirectSource.url;
  2973. this._initiatorCell.appendChild(WebInspector.linkifyRequestAsNode(redirectSource));
  2974. this._appendSubtitle(this._initiatorCell, WebInspector.UIString("Redirect"));
  2975. } else if (initiator.type === "script") {
  2976. var topFrame = initiator.stackTrace[0];
  2977.  
  2978. if (!topFrame.url) {
  2979. this._initiatorCell.addStyleClass("network-dim-cell");
  2980. this._initiatorCell.setTextAndTitle(WebInspector.UIString("Other"));
  2981. return;
  2982. }
  2983. this._initiatorCell.title = topFrame.url + ":" + topFrame.lineNumber;
  2984. var urlElement = this._parentView._linkifier.linkifyLocation(topFrame.url, topFrame.lineNumber - 1, 0);
  2985. this._initiatorCell.appendChild(urlElement);
  2986. this._appendSubtitle(this._initiatorCell, WebInspector.UIString("Script"));
  2987. } else { 
  2988. this._initiatorCell.title = initiator.url + ":" + initiator.lineNumber;
  2989. this._initiatorCell.appendChild(WebInspector.linkifyResourceAsNode(initiator.url, initiator.lineNumber - 1));
  2990. this._appendSubtitle(this._initiatorCell, WebInspector.UIString("Parser"));
  2991. }
  2992. } else {
  2993. this._initiatorCell.addStyleClass("network-dim-cell");
  2994. this._initiatorCell.setTextAndTitle(WebInspector.UIString("Other"));
  2995. }
  2996. },
  2997.  
  2998. _refreshSizeCell: function()
  2999. {
  3000. if (this._request.cached) {
  3001. this._sizeCell.setTextAndTitle(WebInspector.UIString("(from cache)"));
  3002. this._sizeCell.addStyleClass("network-dim-cell");
  3003. } else {
  3004. var resourceSize = typeof this._request.resourceSize === "number" ? Number.bytesToString(this._request.resourceSize) : "?";
  3005. var transferSize = typeof this._request.transferSize === "number" ? Number.bytesToString(this._request.transferSize) : "?";
  3006. this._sizeCell.setTextAndTitle(transferSize);
  3007. this._sizeCell.removeStyleClass("network-dim-cell");
  3008. this._appendSubtitle(this._sizeCell, resourceSize);
  3009. }
  3010. },
  3011.  
  3012. _refreshTimeCell: function()
  3013. {
  3014. if (this._request.duration > 0) {
  3015. this._timeCell.removeStyleClass("network-dim-cell");
  3016. this._timeCell.setTextAndTitle(Number.secondsToString(this._request.duration));
  3017. this._appendSubtitle(this._timeCell, Number.secondsToString(this._request.latency));
  3018. } else {
  3019. this._timeCell.addStyleClass("network-dim-cell");
  3020. this._timeCell.setTextAndTitle(WebInspector.UIString("Pending"));
  3021. }
  3022. },
  3023.  
  3024. _appendSubtitle: function(cellElement, subtitleText)
  3025. {
  3026. var subtitleElement = document.createElement("div");
  3027. subtitleElement.className = "network-cell-subtitle";
  3028. subtitleElement.textContent = subtitleText;
  3029. cellElement.appendChild(subtitleElement);
  3030. },
  3031.  
  3032. refreshGraph: function(calculator)
  3033. {
  3034. var percentages = calculator.computeBarGraphPercentages(this._request);
  3035. this._percentages = percentages;
  3036.  
  3037. this._barAreaElement.removeStyleClass("hidden");
  3038.  
  3039. if (!this._graphElement.hasStyleClass("network-type-" + this._request.type.name())) {
  3040. this._graphElement.removeMatchingStyleClasses("network-type-\\w+");
  3041. this._graphElement.addStyleClass("network-type-" + this._request.type.name());
  3042. }
  3043.  
  3044. this._barLeftElement.style.setProperty("left", percentages.start + "%");
  3045. this._barRightElement.style.setProperty("right", (100 - percentages.end) + "%");
  3046.  
  3047. this._barLeftElement.style.setProperty("right", (100 - percentages.end) + "%");
  3048. this._barRightElement.style.setProperty("left", percentages.middle + "%");
  3049.  
  3050. var labels = calculator.computeBarGraphLabels(this._request);
  3051. this._labelLeftElement.textContent = labels.left;
  3052. this._labelRightElement.textContent = labels.right;
  3053.  
  3054. var tooltip = (labels.tooltip || "");
  3055. this._barLeftElement.title = tooltip;
  3056. this._labelLeftElement.title = tooltip;
  3057. this._labelRightElement.title = tooltip;
  3058. this._barRightElement.title = tooltip;
  3059. },
  3060.  
  3061. _refreshLabelPositions: function()
  3062. {
  3063. if (!this._percentages)
  3064. return;
  3065. this._labelLeftElement.style.removeProperty("left");
  3066. this._labelLeftElement.style.removeProperty("right");
  3067. this._labelLeftElement.removeStyleClass("before");
  3068. this._labelLeftElement.removeStyleClass("hidden");
  3069.  
  3070. this._labelRightElement.style.removeProperty("left");
  3071. this._labelRightElement.style.removeProperty("right");
  3072. this._labelRightElement.removeStyleClass("after");
  3073. this._labelRightElement.removeStyleClass("hidden");
  3074.  
  3075. const labelPadding = 10;
  3076. const barRightElementOffsetWidth = this._barRightElement.offsetWidth;
  3077. const barLeftElementOffsetWidth = this._barLeftElement.offsetWidth;
  3078.  
  3079. if (this._barLeftElement) {
  3080. var leftBarWidth = barLeftElementOffsetWidth - labelPadding;
  3081. var rightBarWidth = (barRightElementOffsetWidth - barLeftElementOffsetWidth) - labelPadding;
  3082. } else {
  3083. var leftBarWidth = (barLeftElementOffsetWidth - barRightElementOffsetWidth) - labelPadding;
  3084. var rightBarWidth = barRightElementOffsetWidth - labelPadding;
  3085. }
  3086.  
  3087. const labelLeftElementOffsetWidth = this._labelLeftElement.offsetWidth;
  3088. const labelRightElementOffsetWidth = this._labelRightElement.offsetWidth;
  3089.  
  3090. const labelBefore = (labelLeftElementOffsetWidth > leftBarWidth);
  3091. const labelAfter = (labelRightElementOffsetWidth > rightBarWidth);
  3092. const graphElementOffsetWidth = this._graphElement.offsetWidth;
  3093.  
  3094. if (labelBefore && (graphElementOffsetWidth * (this._percentages.start / 100)) < (labelLeftElementOffsetWidth + 10))
  3095. var leftHidden = true;
  3096.  
  3097. if (labelAfter && (graphElementOffsetWidth * ((100 - this._percentages.end) / 100)) < (labelRightElementOffsetWidth + 10))
  3098. var rightHidden = true;
  3099.  
  3100. if (barLeftElementOffsetWidth == barRightElementOffsetWidth) {
  3101.  
  3102. if (labelBefore && !labelAfter)
  3103. leftHidden = true;
  3104. else if (labelAfter && !labelBefore)
  3105. rightHidden = true;
  3106. }
  3107.  
  3108. if (labelBefore) {
  3109. if (leftHidden)
  3110. this._labelLeftElement.addStyleClass("hidden");
  3111. this._labelLeftElement.style.setProperty("right", (100 - this._percentages.start) + "%");
  3112. this._labelLeftElement.addStyleClass("before");
  3113. } else {
  3114. this._labelLeftElement.style.setProperty("left", this._percentages.start + "%");
  3115. this._labelLeftElement.style.setProperty("right", (100 - this._percentages.middle) + "%");
  3116. }
  3117.  
  3118. if (labelAfter) {
  3119. if (rightHidden)
  3120. this._labelRightElement.addStyleClass("hidden");
  3121. this._labelRightElement.style.setProperty("left", this._percentages.end + "%");
  3122. this._labelRightElement.addStyleClass("after");
  3123. } else {
  3124. this._labelRightElement.style.setProperty("left", this._percentages.middle + "%");
  3125. this._labelRightElement.style.setProperty("right", (100 - this._percentages.end) + "%");
  3126. }
  3127. },
  3128.  
  3129. __proto__: WebInspector.DataGridNode.prototype
  3130. }
  3131.  
  3132.  
  3133. WebInspector.NetworkDataGridNode.NameComparator = function(a, b)
  3134. {
  3135. var aFileName = a._request.name();
  3136. var bFileName = b._request.name();
  3137. if (aFileName > bFileName)
  3138. return 1;
  3139. if (bFileName > aFileName)
  3140. return -1;
  3141. return 0;
  3142. }
  3143.  
  3144. WebInspector.NetworkDataGridNode.SizeComparator = function(a, b)
  3145. {
  3146. if (b._request.cached && !a._request.cached)
  3147. return 1;
  3148. if (a._request.cached && !b._request.cached)
  3149. return -1;
  3150.  
  3151. if (a._request.resourceSize === b._request.resourceSize)
  3152. return 0;
  3153.  
  3154. return a._request.resourceSize - b._request.resourceSize;
  3155. }
  3156.  
  3157. WebInspector.NetworkDataGridNode.InitiatorComparator = function(a, b)
  3158. {
  3159. if (!a._request.initiator || a._request.initiator.type === "Other")
  3160. return -1;
  3161. if (!b._request.initiator || b._request.initiator.type === "Other")
  3162. return 1;
  3163.  
  3164. if (a._request.initiator.url < b._request.initiator.url)
  3165. return -1;
  3166. if (a._request.initiator.url > b._request.initiator.url)
  3167. return 1;
  3168.  
  3169. return a._request.initiator.lineNumber - b._request.initiator.lineNumber;
  3170. }
  3171.  
  3172. WebInspector.NetworkDataGridNode.RequestPropertyComparator = function(propertyName, revert, a, b)
  3173. {
  3174. var aValue = a._request[propertyName];
  3175. var bValue = b._request[propertyName];
  3176. if (aValue > bValue)
  3177. return revert ? -1 : 1;
  3178. if (bValue > aValue)
  3179. return revert ? 1 : -1;
  3180. return 0;
  3181. }
  3182.